diff --git a/.appveyor.yml b/.appveyor.yml index 97034c7c437bb..7567578af258d 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,12 +2,7 @@ version: "{branch}.build.{build}" image: Visual Studio 2019 -branches: - except: - - PHP-5.6 - - PHP-7.0 - -clone_depth: 64 +clone_depth: 1 skip_commits: files: @@ -41,7 +36,7 @@ environment: - THREAD_SAFE: 1 OPCACHE: 1 PARALLEL: -j2 - INTRINSICS: AVX + INTRINSICS: AVX2 services: # the setup scripts have to be touched, once some other db version is used @@ -51,10 +46,10 @@ services: platform: - x64 - # - x86 + #- x86 build_script: - - appveyor\build.bat + - .github\scripts\windows\build.bat test_script: - - appveyor\test.bat + - .github\scripts\windows\test.bat diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml index abae59c8fdea4..621b18532e05f 100644 --- a/.github/actions/apt-x64/action.yml +++ b/.github/actions/apt-x64/action.yml @@ -18,7 +18,7 @@ runs: libgmp-dev \ libicu-dev \ libtidy-dev \ - libenchant-dev \ + libenchant-2-dev \ libaspell-dev \ libpspell-dev \ libsasl2-dev \ diff --git a/.github/actions/build-libmysqlclient/action.yml b/.github/actions/build-libmysqlclient/action.yml new file mode 100644 index 0000000000000..80a213ada5652 --- /dev/null +++ b/.github/actions/build-libmysqlclient/action.yml @@ -0,0 +1,34 @@ +name: Build libmysqlclient +inputs: + configurationParameters: + default: '' + required: false + libmysql: + required: true + withMysqli: + required: true +runs: + using: composite + steps: + - shell: bash + run: | + set -x + LIBMYSQL=${{ inputs.libmysql }} + MYSQL_BASE=${LIBMYSQL%%-linux-*} + MYSQL_VERSION=${MYSQL_BASE#*-} + MYSQL_DIR=$HOME/$MYSQL_BASE + mkdir -p $MYSQL_DIR + URL=https://cdn.mysql.com/Downloads/MySQL-${MYSQL_VERSION%.*}/$LIBMYSQL + wget -nv $URL + tar -xf $LIBMYSQL --strip-components=1 -C $MYSQL_DIR + PDO_MYSQL=${MYSQL_DIR} + ${{ inputs.withMysqli == 'true' && 'MYSQLI=${MYSQL_DIR}/bin/mysql_config' || '' }} + ./buildconf --force + ./configure ${{ inputs.configurationParameters }} \ + --enable-option-checking=fatal \ + --disable-all \ + --enable-pdo \ + --with-pdo-mysql=${PDO_MYSQL} \ + ${{ inputs.withMysqli == 'true' && '--with-mysqli=${MYSQLI}' || '' }} + make clean + make -j$(/usr/bin/nproc) >/dev/null diff --git a/.github/actions/configure-x64/action.yml b/.github/actions/configure-x64/action.yml index 5b5583918bcfe..ee802334490ae 100644 --- a/.github/actions/configure-x64/action.yml +++ b/.github/actions/configure-x64/action.yml @@ -72,7 +72,6 @@ runs: --with-snmp \ --with-unixODBC \ --with-imap \ - --with-kerberos \ --with-imap-ssl \ --with-pdo-odbc=unixODBC,/usr \ --with-pdo-oci=shared,instantclient,/opt/oracle/instantclient \ diff --git a/.github/actions/test-libmysqlclient/action.yml b/.github/actions/test-libmysqlclient/action.yml new file mode 100644 index 0000000000000..c7b1a4b430fb9 --- /dev/null +++ b/.github/actions/test-libmysqlclient/action.yml @@ -0,0 +1,21 @@ +name: Test libmysqlclient +inputs: + withMysqli: + required: true +runs: + using: composite + steps: + - shell: bash + run: | + set -x + ${{ inputs.withMysqli == 'true' && 'export MYSQL_TEST_USER=root' || '' }} + ${{ inputs.withMysqli == 'true' && 'export MYSQL_TEST_PASSWD=root' || '' }} + export PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test" + export PDO_MYSQL_TEST_HOST=127.0.0.1 + export PDO_MYSQL_TEST_USER=root + export PDO_MYSQL_TEST_PASS=root + export REPORT_EXIT_STATUS=no + sapi/cli/php run-tests.php -P -q \ + -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \ + --offline --show-diff --show-slow 1000 --set-timeout 120 \ + ext/pdo_mysql diff --git a/.github/nightly_matrix.php b/.github/nightly_matrix.php index a099a3ba2ad67..bab4e83ea17cf 100644 --- a/.github/nightly_matrix.php +++ b/.github/nightly_matrix.php @@ -42,7 +42,7 @@ function get_branches() { return get_branch_matrix($changed_branches); } -function get_asan_matrix(array $branches) { +function get_matrix_include(array $branches) { $jobs = []; foreach ($branches as $branch) { $jobs[] = [ @@ -52,7 +52,26 @@ function get_asan_matrix(array $branches) { 'zts' => true, 'configuration_parameters' => "CFLAGS='-fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC' LDFLAGS='-fsanitize=undefined,address'", 'run_tests_parameters' => '--asan', + 'timeout_minutes' => 480, ]; + if ($branch['ref'] !== 'PHP-8.0') { + $jobs[] = [ + 'name' => '_REPEAT', + 'branch' => $branch, + 'debug' => true, + 'zts' => false, + 'run_tests_parameters' => '--repeat 2', + 'timeout_minutes' => 360, + ]; + $jobs[] = [ + 'name' => '_VARIATION', + 'branch' => $branch, + 'debug' => true, + 'zts' => true, + 'configuration_parameters' => "CFLAGS='-DZEND_RC_DEBUG=1 -DPROFITABILITY_CHECKS=0 -DZEND_VERIFY_FUNC_INFO=1'", + 'timeout_minutes' => 360, + ]; + } } return $jobs; } @@ -65,7 +84,7 @@ function get_asan_matrix(array $branches) { } $branches = get_branches(); -$asan_matrix = get_asan_matrix($branches); +$matrix_include = get_matrix_include($branches); echo '::set-output name=branches::' . json_encode($branches, JSON_UNESCAPED_SLASHES) . "\n"; -echo '::set-output name=asan-matrix::' . json_encode($asan_matrix, JSON_UNESCAPED_SLASHES) . "\n"; +echo '::set-output name=matrix-include::' . json_encode($matrix_include, JSON_UNESCAPED_SLASHES) . "\n"; diff --git a/.github/scripts/setup-slapd.sh b/.github/scripts/setup-slapd.sh index 7ea3cb33b3d0e..b9cb1a4ff7a95 100755 --- a/.github/scripts/setup-slapd.sh +++ b/.github/scripts/setup-slapd.sh @@ -1,5 +1,5 @@ #!/bin/sh -set -ev +set -ex # Create TLS certificate sudo mkdir -p /etc/ldap/ssl diff --git a/appveyor/build.bat b/.github/scripts/windows/build.bat similarity index 94% rename from appveyor/build.bat rename to .github/scripts/windows/build.bat index a6b34a0314f63..cb85f605c610e 100644 --- a/appveyor/build.bat +++ b/.github/scripts/windows/build.bat @@ -38,7 +38,7 @@ if not exist "%SDK_RUNNER%" ( exit /b 3 ) -cmd /c %SDK_RUNNER% -t %APPVEYOR_BUILD_FOLDER%\appveyor\build_task.bat +cmd /c %SDK_RUNNER% -t %APPVEYOR_BUILD_FOLDER%\.github\scripts\windows\build_task.bat if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/appveyor/build_task.bat b/.github/scripts/windows/build_task.bat similarity index 100% rename from appveyor/build_task.bat rename to .github/scripts/windows/build_task.bat diff --git a/appveyor/test.bat b/.github/scripts/windows/test.bat similarity index 71% rename from appveyor/test.bat rename to .github/scripts/windows/test.bat index 6d4c5fa408f3b..f51a14b9dc64c 100644 --- a/appveyor/test.bat +++ b/.github/scripts/windows/test.bat @@ -6,7 +6,7 @@ if not exist "%SDK_RUNNER%" ( exit /b 3 ) -cmd /c %SDK_RUNNER% -t %APPVEYOR_BUILD_FOLDER%\appveyor\test_task.bat +cmd /c %SDK_RUNNER% -t %APPVEYOR_BUILD_FOLDER%\.github\scripts\windows\test_task.bat if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/appveyor/test_task.bat b/.github/scripts/windows/test_task.bat similarity index 96% rename from appveyor/test_task.bat rename to .github/scripts/windows/test_task.bat index fb58e9bc438e6..39f0eb07c048a 100644 --- a/appveyor/test_task.bat +++ b/.github/scripts/windows/test_task.bat @@ -64,6 +64,8 @@ rem set SSLEAY_CONF= rem prepare for OPcache if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=16M +rem work-around for failing to dl(mysqli) with OPcache (https://github.com/php/php-src/issues/8508) +if "%OPCACHE%" equ "1" set OPCACHE_OPTS=%OPCACHE_OPTS% -d extension=mysqli rem prepare for enchant mkdir C:\usr\local\lib\enchant-2 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 38d85d2b7224e..2c7d547437805 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest outputs: branches: ${{ steps.set-matrix.outputs.branches }} - asan-matrix: ${{ steps.set-matrix.outputs.asan-matrix }} + matrix-include: ${{ steps.set-matrix.outputs.matrix-include }} steps: - uses: actions/checkout@v2 with: @@ -37,11 +37,16 @@ jobs: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} + configuration_parameters: [''] debug: [true, false] + name: [''] + run_tests_parameters: [''] + timeout_minutes: [360] zts: [true, false] - include: ${{ fromJson(needs.GENERATE_MATRIX.outputs.asan-matrix) }} + include: ${{ fromJson(needs.GENERATE_MATRIX.outputs.matrix-include) }} name: "${{ matrix.branch.name }}_LINUX_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-20.04 + timeout-minutes: ${{ matrix.timeout_minutes }} steps: - name: git checkout uses: actions/checkout@v2 @@ -156,6 +161,7 @@ jobs: - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files COVERAGE_DEBUG_NTS: + if: github.repository_owner == 'php' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-20.04 steps: - name: git checkout @@ -188,3 +194,320 @@ jobs: - name: Upload Test Coverage to Codecov.io if: always() run: bash <(curl -s https://codecov.io/bash) + COMMUNITY: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} + name: "${{ matrix.branch.name }}_COMMUNITY" + runs-on: ubuntu-20.04 + env: + UBSAN_OPTIONS: print_stacktrace=1 + USE_ZEND_ALLOC: 0 + USE_TRACKED_ALLOC: 1 + steps: + - name: git checkout + uses: actions/checkout@v2 + with: + ref: ${{ matrix.branch.ref }} + - name: apt + uses: ./.github/actions/apt-x64 + - name: ./configure + uses: ./.github/actions/configure-x64 + with: + configurationParameters: >- + --enable-debug + --enable-zts + CFLAGS='-fsanitize=undefined,address -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC' + LDFLAGS='-fsanitize=undefined,address' + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + run: | + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + - name: Enable Opcache and JIT + run: | + echo zend_extension=opcache.so > /etc/php.d/opcache.ini + echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini + echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini + echo opcache.jit_buffer_size=1G >> /etc/php.d/opcache.ini + - name: Test Laravel + if: matrix.branch.ref != 'PHP-8.0' + run: | + git clone https://github.com/laravel/framework.git --branch=master --depth=1 + cd framework + git rev-parse HEAD + php /usr/bin/composer install --no-progress --ignore-platform-reqs + # Hack to disable a test that hangs + php -r '$c = file_get_contents("tests/Filesystem/FilesystemTest.php"); $c = str_replace("*/\n public function testSharedGet()", "* @group skip\n */\n public function testSharedGet()", $c); file_put_contents("tests/Filesystem/FilesystemTest.php", $c);' + export ASAN_OPTIONS=exitcode=139 + php vendor/bin/phpunit --exclude-group skip || EXIT_CODE=$? + if [ $EXIT_CODE -gt 128 ]; then + exit 1 + fi + - name: Test Symfony + if: matrix.branch.ref != 'PHP-8.0' + run: | + git clone https://github.com/symfony/symfony.git --depth=1 + cd symfony + git rev-parse HEAD + php /usr/bin/composer install --no-progress --ignore-platform-reqs + php ./phpunit install + # Test causes a heap-buffer-overflow but I cannot reproduce it locally... + php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "/** @group skip */\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);' + # 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("*/\n public function testCastNonTrailingCharPointer()", "* @group skip\n */\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);' + export ASAN_OPTIONS=exitcode=139 + export SYMFONY_DEPRECATIONS_HELPER=max[total]=999 + X=0 + for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do + php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient --exclude-group skip || EXIT_CODE=$? + if [ $EXIT_CODE -gt 128 ]; then + X=1; + fi + done + exit $X + - name: Test PHPUnit + if: always() + run: | + git clone https://github.com/sebastianbergmann/phpunit.git --branch=main --depth=1 + cd phpunit + git rev-parse HEAD + export ASAN_OPTIONS=exitcode=139 + php /usr/bin/composer install --no-progress --ignore-platform-reqs + php ./phpunit || EXIT_CODE=$? + if [ $EXIT_CODE -gt 128 ]; then + exit 1 + fi + - name: 'Symfony Preloading' + if: matrix.branch.ref != 'PHP-8.0' + run: | + php /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress --ignore-platform-reqs + cd symfony_demo + git rev-parse HEAD + sed -i 's/PHP_SAPI/"cli-server"/g' var/cache/dev/App_KernelDevDebugContainer.preload.php + php -d opcache.preload=var/cache/dev/App_KernelDevDebugContainer.preload.php public/index.php + OPCACHE_VARIATION: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} + name: "${{ matrix.branch.name }}_OPCACHE_VARIATION" + runs-on: ubuntu-20.04 + steps: + - name: git checkout + uses: actions/checkout@v2 + with: + ref: ${{ matrix.branch.ref }} + - name: Create MSSQL container + uses: ./.github/actions/setup-mssql + - name: Create Oracle container + uses: ./.github/actions/setup-oracle + - name: apt + uses: ./.github/actions/apt-x64 + - name: ./configure + uses: ./.github/actions/configure-x64 + with: + configurationParameters: >- + --enable-debug --disable-zts + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + uses: ./.github/actions/setup-x64 + - name: Test File Cache (prime shm) + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + --file-cache-prime + - name: Test File Cache (prime shm, use shm) + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + --file-cache-use + - name: Test File Cache (prime shm, use file) + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + --file-cache-use + -d opcache.file_cache_only=1 + - name: Test File Cache Only (prime) + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + --file-cache-prime + -d opcache.file_cache_only=1 + - name: Test File Cache Only (use) + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + --file-cache-use + -d opcache.file_cache_only=1 + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + MSAN: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} + name: "${{ matrix.branch.name }}_MSAN" + runs-on: ubuntu-22.04 + steps: + - name: git checkout + uses: actions/checkout@v2 + with: + ref: ${{ matrix.branch.ref }} + - name: apt + uses: ./.github/actions/apt-x64 + - name: ./configure + run: | + export CC=clang + export CXX=clang++ + export CFLAGS="-DZEND_TRACK_ARENA_ALLOC" + ./buildconf --force + # msan requires all used libraries to be instrumented, + # so we should avoiding linking against anything but libc here + ./configure \ + --enable-debug \ + --enable-zts \ + --enable-option-checking=fatal \ + --prefix=/usr \ + --without-sqlite3 \ + --without-pdo-sqlite \ + --without-libxml \ + --disable-dom \ + --disable-simplexml \ + --disable-xml \ + --disable-xmlreader \ + --disable-xmlwriter \ + --without-pcre-jit \ + --disable-opcache-jit \ + --enable-phpdbg \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + --disable-mysqlnd-compression-support \ + --without-pear \ + --enable-exif \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --enable-mbstring \ + --disable-mbregex \ + --enable-sockets \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --enable-zend-test \ + --enable-werror \ + --enable-memory-sanitizer \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + run: | + sudo make install + sudo mkdir /etc/php.d + sudo chmod 777 /etc/php.d + echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini + echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini + - name: Setup + run: | + set -x + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + # Ensure local_infile tests can run. + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + sudo locale-gen de_DE + - name: Test + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + --msan + - name: Test Opcache + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + --msan + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + LIBMYSQLCLIENT: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} + exclude: + - branch: { name: 'PHP-80', ref: 'PHP-8.0' } + name: "${{ matrix.branch.name }}_LIBMYSQLCLIENT" + runs-on: ubuntu-20.04 + steps: + - name: git checkout + uses: actions/checkout@v2 + with: + ref: ${{ matrix.branch.ref }} + - name: apt + run: | + sudo apt-get update -y | true + sudo apt install bison re2c + - name: Setup + run: | + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + # Ensure local_infile tests can run. + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + # Does not support caching_sha2_auth :( + # - name: Build mysql-5.6 + # uses: ./.github/actions/build-libmysqlclient + # with: + # libmysql: mysql-5.6.49-linux-glibc2.12-x86_64.tar.gz + # - name: Test mysql-5.6 + # uses: ./.github/actions/test-libmysqlclient + - name: Build mysql-5.7 + uses: ./.github/actions/build-libmysqlclient + with: + libmysql: mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz + withMysqli: ${{ matrix.branch.ref == 'PHP-8.1' }} + - name: Test mysql-5.7 + uses: ./.github/actions/test-libmysqlclient + with: + withMysqli: ${{ matrix.branch.ref == 'PHP-8.1' }} + - name: Build mysql-8.0 + uses: ./.github/actions/build-libmysqlclient + with: + # FIXME: There are new warnings + # configurationParameters: --enable-werror + libmysql: mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz + withMysqli: ${{ matrix.branch.ref == 'PHP-8.1' }} + - name: Test mysql-8.0 + uses: ./.github/actions/test-libmysqlclient + with: + withMysqli: ${{ matrix.branch.ref == 'PHP-8.1' }} + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files diff --git a/NEWS b/NEWS index 94c8fea4ef75d..10d8b56796839 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,38 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.11 +27 Oct 2022, PHP 8.1.12 + +- Core: + . Fixes segfault with Fiber on FreeBSD i386 architecture. (David Carlier) + +- Fileinfo: + . Fixed bug GH-8805 (finfo returns wrong mime type for woff/woff2 files). + (Anatol) + +- GD: + . Fixed bug #81739: OOB read due to insufficient input validation in + imageloadfont(). (CVE-2022-31630) (cmb) + +- Hash: + . Fixed bug #81738: buffer overflow in hash_update() on long parameter. + (CVE-2022-37454) (nicky at mouha dot be) + +- MBString: + - Fixed bug GH-9683 (Problem when ISO-2022-JP-MS is specified in + mb_ encode_mimeheader). (Alex Dowad) + +- Opcache: + . Added indirect call reduction for jit on x86 architectures. (wxue1) + +- Session: + . Fixed bug GH-9583 (session_create_id() fails with user defined save handler + that doesn't have a validateId() method). (Girgias) + +- Streams: + . Fixed bug GH-9590 (stream_select does not abort upon exception or empty + valid fd set). (Arnaud) + +29 Sep 2022, PHP 8.1.11 - Core: . Fixed bug GH-9323 (Crash in ZEND_RETURN/GC/zend_call_function) @@ -9,6 +41,8 @@ PHP NEWS Christian Schneider) . Fixed bug GH-9447 (Invalid class FQN emitted by AST dump for new and class constants in constant expressions). (ilutov) + . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones + that have a specific semantic meaning. (CVE-2022-31629). (Derick) - DOM: . Fixed bug #79451 (DOMDocument->replaceChild on doctype causes double free). @@ -35,6 +69,10 @@ PHP NEWS . Fixed bug GH-9411 (PgSQL large object resource is incorrectly closed). (Yurunsoft) +- Phar: + . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. + (CVE-2022-31628). (cmb) + - Reflection: . Fixed bug GH-8932 (ReflectionFunction provides no way to get the called class of a Closure). (cmb, Nicolas Grekas) diff --git a/Zend/tests/gc_046.phpt b/Zend/tests/gc_046.phpt new file mode 100644 index 0000000000000..74481fb76a7ea --- /dev/null +++ b/Zend/tests/gc_046.phpt @@ -0,0 +1,23 @@ +--TEST-- +GC 046: Leak in User Iterator +--INI-- +zend.enable_gc=1 +--FILE-- +iterator = new ArrayIterator($this); + } + function filter() { + $this->iterator = new CallbackFilterIterator($this->iterator, fn() => true); + $this->iterator->rewind(); + } +} + +$action=new Action; +$action->filter(); +$action->filter(); +?> +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/temporary_cleaning_017.phpt b/Zend/tests/temporary_cleaning_017.phpt new file mode 100644 index 0000000000000..dbd0ef336fcf6 --- /dev/null +++ b/Zend/tests/temporary_cleaning_017.phpt @@ -0,0 +1,23 @@ +--TEST-- +Live range & free on return & TMP var of RETURN opcode +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "y" in %stemporary_cleaning_017.php:5 +Stack trace: +#0 %stemporary_cleaning_017.php(10): bar->__destruct() +#1 {main} + thrown in %stemporary_cleaning_017.php on line 5 diff --git a/Zend/zend.h b/Zend/zend.h index 632869a9b37d3..958d44f45b6af 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.11-dev" +#define ZEND_VERSION "4.1.12" #define ZEND_ENGINE_3 diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index b032d1d4e0b4c..3297b9f82aac6 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -185,8 +185,15 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter) ZEND_API HashTable *zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n) { zend_user_iterator *iter = (zend_user_iterator*)_iter; - *table = &iter->it.data; - *n = 1; + if (Z_ISUNDEF(iter->value)) { + *table = &iter->it.data; + *n = 1; + } else { + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + zend_get_gc_buffer_add_zval(gc_buffer, &iter->it.data); + zend_get_gc_buffer_add_zval(gc_buffer, &iter->value); + zend_get_gc_buffer_use(gc_buffer, table, n); + } return NULL; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 5996b93a78287..a0c23a74a6def 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7861,6 +7861,19 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) */ const zend_live_range *range = find_live_range( &EX(func)->op_array, throw_op_num, throw_op->op1.var); + /* free op1 of the corresponding RETURN */ + for (i = throw_op_num; i < range->end; i++) { + if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE + || EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) { + /* pass */ + } else { + if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN + && (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) { + zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var)); + } + break; + } + } throw_op_num = range->end; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 41d3d8f59c2f0..fde07d6196c35 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3085,6 +3085,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( */ const zend_live_range *range = find_live_range( &EX(func)->op_array, throw_op_num, throw_op->op1.var); + /* free op1 of the corresponding RETURN */ + for (i = throw_op_num; i < range->end; i++) { + if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE + || EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) { + /* pass */ + } else { + if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN + && (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) { + zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var)); + } + break; + } + } throw_op_num = range->end; } diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1ae502c66f811..7965a71c4c7dc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -44,36 +44,3 @@ jobs: parameters: configurationName: I386_RELEASE_ZTS configurationParameters: '--disable-debug --enable-zts' - - template: azure/msan_job.yml - parameters: - configurationName: DEBUG_ZTS_MSAN - configurationParameters: '--enable-debug --enable-zts' - runTestsParameters: --msan - timeoutInMinutes: 90 - - template: azure/community_job.yml - parameters: - configurationName: COMMUNITY - configurationParameters: >- - --enable-debug --enable-zts --enable-address-sanitizer --enable-undefined-sanitizer - CFLAGS='-fno-sanitize-recover' - timeoutInMinutes: 90 - - template: azure/opcache_variation_job.yml - parameters: - configurationName: DEBUG_NTS_OPCACHE - configurationParameters: '--enable-debug --disable-zts' - timeoutInMinutes: 120 - - template: azure/job.yml - parameters: - configurationName: DEBUG_NTS_REPEAT - configurationParameters: '--enable-debug --disable-zts' - runTestsParameters: '--repeat 2' - - template: azure/libmysqlclient_job.yml - parameters: - configurationName: LIBMYSQLCLIENT_DEBUG_NTS - configurationParameters: '--enable-debug --disable-zts' - - template: azure/job.yml - parameters: - configurationName: VARIATION_DEBUG_ZTS - configurationParameters: >- - --enable-debug --enable-zts - CFLAGS="-DZEND_RC_DEBUG=1 -DPROFITABILITY_CHECKS=0 -DZEND_VERIFY_FUNC_INFO=1" diff --git a/azure/apt.yml b/azure/apt.yml deleted file mode 100644 index 9166509dccae7..0000000000000 --- a/azure/apt.yml +++ /dev/null @@ -1,64 +0,0 @@ -parameters: - packages: '' - -steps: - - script: | - sudo apt-get update -y | true - sudo apt install bison \ - re2c \ - locales \ - ldap-utils \ - openssl \ - slapd \ - language-pack-de \ - re2c \ - libgmp-dev \ - libicu-dev \ - libtidy-dev \ - libenchant-dev \ - libaspell-dev \ - libpspell-dev \ - libsasl2-dev \ - libxpm-dev \ - libzip-dev \ - libsqlite3-dev \ - libwebp-dev \ - libonig-dev \ - libkrb5-dev \ - libgssapi-krb5-2 \ - libcurl4-openssl-dev \ - libxml2-dev \ - libxslt1-dev \ - libpq-dev \ - libreadline-dev \ - libldap2-dev \ - libsodium-dev \ - libargon2-0-dev \ - libmm-dev \ - libsnmp-dev \ - postgresql \ - postgresql-contrib \ - snmpd \ - snmp-mibs-downloader \ - freetds-dev \ - unixodbc-dev \ - llvm \ - libc-client-dev \ - libkrb5-dev \ - dovecot-core \ - dovecot-pop3d \ - dovecot-imapd \ - sendmail \ - firebird-dev \ - ${{ parameters.packages }} - displayName: 'APT' - - script: | - mkdir /opt/oracle - wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip - unzip instantclient-basiclite-linuxx64.zip - wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-sdk-linuxx64.zip - unzip instantclient-sdk-linuxx64.zip - mv instantclient_*_* /opt/oracle/instantclient - # Interferes with libldap2 headers. - rm /opt/oracle/instantclient/sdk/include/ldap.h - displayName: 'Install Oracle Instant Client' diff --git a/azure/community_job.yml b/azure/community_job.yml deleted file mode 100644 index a7bfacb9e6c0a..0000000000000 --- a/azure/community_job.yml +++ /dev/null @@ -1,108 +0,0 @@ -parameters: - configurationName: '' - configurationParameters: '' - timeoutInMinutes: 60 - -# The purpose of the job is to test open-source community projects against an aggressive -# debug build, that enables assertions, as well as the address and UB sanitizers. However, -# we are only interested in finding assertion failures, segfaults and sanitizer violations, -# and don't care about the actual test results, as there will commonly be failures for -# pre-release versions of PHP. -# -# Because exit() in PHP results in an unclean shutdown, test runs are patching phpunit to -# avoid the exit, which allows us to also check for memory leaks. Otherwise we use -# USE_TRACKED_ALLOC=1 to avoid reporting of leaks that will be handled by ZMM. -jobs: - - job: ${{ parameters.configurationName }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - pool: - vmImage: 'ubuntu-20.04' - variables: - ubsan_options: 'print_stacktrace=1' - steps: - - template: apt.yml - - template: configure.yml - parameters: - configurationParameters: ${{ parameters.configurationParameters }} - - script: make -j$(/usr/bin/nproc) >/dev/null - displayName: 'Make Build' - - script: | - sudo make install - sudo mkdir /etc/php.d - sudo chmod 777 /etc/php.d - echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini - # Run with opcache to also catch optimizer bugs. - echo zend_extension=opcache.so > /etc/php.d/opcache.ini - echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini - echo opcache.jit_buffer_size=1G >> /etc/php.d/opcache.ini - displayName: 'Install Build' - - script: | - git clone https://github.com/laravel/framework.git --branch=master --depth=1 - cd framework - git rev-parse HEAD - php8.0 /usr/bin/composer install --no-progress - # Hack to disable a test that hangs on azure - sed -i 's/PHP_OS/"Darwin"/' tests/Filesystem/FilesystemTest.php - export USE_ZEND_ALLOC=0 - export ASAN_OPTIONS=exitcode=139 - php vendor/bin/phpunit - if [ $? -gt 128 ]; then - exit 1 - fi - displayName: 'Test Laravel' - - script: | - git clone https://github.com/symfony/symfony.git --depth=1 - cd symfony - git rev-parse HEAD - php8.0 /usr/bin/composer install --no-progress - php8.0 ./phpunit install - export USE_ZEND_ALLOC=0 - export USE_TRACKED_ALLOC=1 - export ASAN_OPTIONS=exitcode=139 - export SYMFONY_DEPRECATIONS_HELPER=max[total]=999 - X=0 - for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do - php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient; - if [ $? -gt 128 ]; then - X=1; - fi - done - exit $X - displayName: 'Test Symfony' - condition: or(succeeded(), failed()) - - script: | - git clone https://github.com/amphp/amp.git --branch=master --depth=1 - cd amp - git rev-parse HEAD - php /usr/bin/composer install --no-progress --ignore-platform-reqs - export USE_ZEND_ALLOC=0 - sed -i 's/$exit = true/$exit = false/g' vendor/phpunit/phpunit/src/TextUI/Command.php - php vendor/bin/phpunit - displayName: 'Test Amphp' - condition: or(succeeded(), failed()) - - script: | - git clone https://github.com/sebastianbergmann/phpunit.git --branch=master --depth=1 - cd phpunit - git rev-parse HEAD - export USE_ZEND_ALLOC=0 - export USE_TRACKED_ALLOC=1 - export ASAN_OPTIONS=exitcode=139 - php8.0 /usr/bin/composer install --no-progress - php ./phpunit - if [ $? -gt 128 ]; then - exit 1 - fi - displayName: 'Test PHPUnit' - condition: or(succeeded(), failed()) - - script: | - php8.0 /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress - cd symfony_demo - git rev-parse HEAD - export USE_ZEND_ALLOC=0 - export USE_TRACKED_ALLOC=1 - sed -i 's/PHP_SAPI/"cli-server"/g' var/cache/dev/App_KernelDevDebugContainer.preload.php - php -d opcache.preload=var/cache/dev/App_KernelDevDebugContainer.preload.php public/index.php - displayName: 'Symfony Preloading' - condition: or(succeeded(), failed()) diff --git a/azure/configure.yml b/azure/configure.yml deleted file mode 100644 index cf2e3bb2a2d8b..0000000000000 --- a/azure/configure.yml +++ /dev/null @@ -1,73 +0,0 @@ -parameters: - configurationParameters: '' - -steps: -- script: | - ./buildconf --force - ./configure ${{ parameters.configurationParameters }} \ - --enable-option-checking=fatal \ - --prefix=/usr \ - --enable-phpdbg \ - --enable-fpm \ - --with-pdo-mysql=mysqlnd \ - --with-mysqli=mysqlnd \ - --with-pgsql \ - --with-pdo-pgsql \ - --with-pdo-sqlite \ - --enable-intl \ - --without-pear \ - --enable-gd \ - --with-jpeg \ - --with-webp \ - --with-freetype \ - --with-xpm \ - --enable-exif \ - --with-zip \ - --with-zlib \ - --with-zlib-dir=/usr \ - --enable-soap \ - --enable-xmlreader \ - --with-xsl \ - --with-tidy \ - --enable-sysvsem \ - --enable-sysvshm \ - --enable-shmop \ - --enable-pcntl \ - --with-readline \ - --enable-mbstring \ - --with-curl \ - --with-gettext \ - --enable-sockets \ - --with-bz2 \ - --with-openssl \ - --with-gmp \ - --enable-bcmath \ - --enable-calendar \ - --enable-ftp \ - --with-pspell=/usr \ - --with-enchant=/usr \ - --with-kerberos \ - --enable-sysvmsg \ - --with-ffi \ - --enable-zend-test \ - --enable-dl-test=shared \ - --with-ldap \ - --with-ldap-sasl \ - --with-password-argon2 \ - --with-mhash \ - --with-sodium \ - --enable-dba \ - --with-snmp \ - --with-unixODBC \ - --with-imap \ - --with-kerberos \ - --with-imap-ssl \ - --with-pdo-odbc=unixODBC,/usr \ - --with-pdo-firebird \ - --with-pdo-dblib \ - --with-pdo-oci=shared,instantclient,/opt/oracle/instantclient \ - --with-oci8=shared,instantclient,/opt/oracle/instantclient \ - --enable-werror \ - --with-config-file-path=/etc \ - --with-config-file-scan-dir=/etc/php.d - displayName: 'Configure Build' diff --git a/azure/install.yml b/azure/install.yml deleted file mode 100644 index 3cd6122071cf6..0000000000000 --- a/azure/install.yml +++ /dev/null @@ -1,11 +0,0 @@ -steps: - - script: | - set -e - sudo make install - sudo mkdir /etc/php.d - sudo chmod 777 /etc/php.d - echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini - echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini - displayName: 'Install Build' diff --git a/azure/job.yml b/azure/job.yml deleted file mode 100644 index f354c4d717504..0000000000000 --- a/azure/job.yml +++ /dev/null @@ -1,25 +0,0 @@ -parameters: - configurationName: '' - configurationParameters: '' - runTestsParameters: '' - timeoutInMinutes: 75 - -jobs: - - job: ${{ parameters.configurationName }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - pool: - vmImage: 'ubuntu-20.04' - steps: - - template: mssql.yml - - template: apt.yml - - template: configure.yml - parameters: - configurationParameters: ${{ parameters.configurationParameters }} - - script: make -j$(/usr/bin/nproc) >/dev/null - displayName: 'Make Build' - - template: install.yml - - template: setup.yml - - template: tests.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsParameters: ${{ parameters.runTestsParameters }} diff --git a/azure/libmysqlclient_job.yml b/azure/libmysqlclient_job.yml deleted file mode 100644 index 4eb998014c316..0000000000000 --- a/azure/libmysqlclient_job.yml +++ /dev/null @@ -1,37 +0,0 @@ -parameters: - configurationName: '' - configurationParameters: '' - runTestsParameters: '' - timeoutInMinutes: 60 - -jobs: - - job: ${{ parameters.configurationName }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - pool: - vmImage: 'ubuntu-20.04' - steps: - - script: | - sudo apt-get update -y | true - sudo apt install bison re2c - displayName: 'APT' - - script: | - set -o - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" - # Ensure local_infile tests can run. - mysql -uroot -proot -e "SET GLOBAL local_infile = true" - displayName: 'Setup MySQL server' - # Does not support caching_sha2_auth :( - #- template: libmysqlclient_test.yml - # parameters: - # configurationName: ${{ parameters.configurationName }} - MySQL 5.6.49 - # libmysql: mysql-5.6.49-linux-glibc2.12-x86_64.tar.gz - - template: libmysqlclient_test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - MySQL 5.7.38 - libmysql: mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz - - template: libmysqlclient_test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - MySQL 8.0.27 - libmysql: mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz - configurationParameters: ${{ parameters.configurationParameters }} --enable-werror diff --git a/azure/libmysqlclient_test.yml b/azure/libmysqlclient_test.yml deleted file mode 100644 index c163345dc4db4..0000000000000 --- a/azure/libmysqlclient_test.yml +++ /dev/null @@ -1,53 +0,0 @@ -parameters: - configurationName: '' - configurationParameters: '' - libmysql: '' - -steps: - - script: | - set -e - LIBMYSQL=${{ parameters.libmysql }} - MYSQL_BASE=${LIBMYSQL%%-linux-*} - MYSQL_VERSION=${MYSQL_BASE#*-} - MYSQL_DIR=$HOME/$MYSQL_BASE - mkdir -p $MYSQL_DIR - URL=https://cdn.mysql.com/Downloads/MySQL-${MYSQL_VERSION%.*}/$LIBMYSQL - wget -nv $URL - tar -xf $LIBMYSQL --strip-components=1 -C $MYSQL_DIR - PDO_MYSQL=${MYSQL_DIR} - MYSQLI=${MYSQL_DIR}/bin/mysql_config - ./buildconf --force - ./configure ${{ parameters.configurationParameters }} \ - --enable-option-checking=fatal \ - --disable-all \ - --enable-pdo \ - --with-pdo-mysql=${PDO_MYSQL} \ - --with-mysqli=${MYSQLI} - make clean - make -j$(/usr/bin/nproc) >/dev/null - displayName: 'Build ${{ parameters.configurationName }}' - condition: or(succeeded(), failed()) - - script: | - export MYSQL_TEST_USER=root - export MYSQL_TEST_PASSWD=root - export PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test" - export PDO_MYSQL_TEST_HOST=127.0.0.1 - export PDO_MYSQL_TEST_USER=root - export PDO_MYSQL_TEST_PASS=root - export TEST_PHP_JUNIT=junit.xml - export REPORT_EXIT_STATUS=no - rm -rf junit.xml | true - sapi/cli/php run-tests.php -P -q \ - -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \ - --offline --show-diff --show-slow 1000 --set-timeout 120 \ - ext/pdo_mysql - displayName: 'Test ${{ parameters.configurationName }}' - condition: or(succeeded(), failed()) - - task: PublishTestResults@2 - inputs: - testResultsFormat: 'JUnit' - testResultsFiles: junit.xml - testRunTitle: '${{ parameters.configurationName }}' - failTaskOnFailedTests: true - displayName: 'Export ${{ parameters.configurationName }} Results' - condition: or(succeeded(), failed()) diff --git a/azure/msan_job.yml b/azure/msan_job.yml deleted file mode 100644 index 28f9dbe2015a0..0000000000000 --- a/azure/msan_job.yml +++ /dev/null @@ -1,81 +0,0 @@ -parameters: - configurationName: '' - configurationParameters: '' - runTestsParameters: '' - timeoutInMinutes: 60 - -jobs: - - job: ${{ parameters.configurationName }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - pool: - vmImage: 'ubuntu-20.04' - steps: - - template: apt.yml - - script: | - export CC=clang - export CXX=clang++ - export CFLAGS="-DZEND_TRACK_ARENA_ALLOC" - ./buildconf --force - # msan requires all used libraries to be instrumented, - # so we should avoiding linking against anything but libc here - ./configure ${{ parameters.configurationParameters }} \ - --enable-option-checking=fatal \ - --prefix=/usr \ - --without-sqlite3 \ - --without-pdo-sqlite \ - --without-libxml \ - --disable-dom \ - --disable-simplexml \ - --disable-xml \ - --disable-xmlreader \ - --disable-xmlwriter \ - --without-pcre-jit \ - --disable-opcache-jit \ - --enable-phpdbg \ - --enable-fpm \ - --with-pdo-mysql=mysqlnd \ - --with-mysqli=mysqlnd \ - --disable-mysqlnd-compression-support \ - --without-pear \ - --enable-exif \ - --enable-sysvsem \ - --enable-sysvshm \ - --enable-shmop \ - --enable-pcntl \ - --enable-mbstring \ - --disable-mbregex \ - --enable-sockets \ - --enable-bcmath \ - --enable-calendar \ - --enable-ftp \ - --enable-zend-test \ - --enable-dl-test=shared \ - --enable-werror \ - --enable-memory-sanitizer \ - --with-config-file-path=/etc \ - --with-config-file-scan-dir=/etc/php.d - displayName: 'Configure Build' - - script: make -j$(/usr/bin/nproc) >/dev/null - displayName: 'Make Build' - - script: | - sudo make install - sudo mkdir /etc/php.d - sudo chmod 777 /etc/php.d - echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini - displayName: 'Install Build' - - script: | - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" - displayName: 'Setup' - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsParameters: ${{ parameters.runTestsParameters }} - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'OpCache' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 diff --git a/azure/mssql.yml b/azure/mssql.yml deleted file mode 100644 index 09b2af9617e65..0000000000000 --- a/azure/mssql.yml +++ /dev/null @@ -1,5 +0,0 @@ -# this template should be included close to the beginning, before setup.yml -# the container needs time to come up or the sqlcmd operation in setup.yml will have a login timeout -steps: - - script: docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=" -p 1433:1433 --name sql1 -h sql1 -d mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04 - displayName: 'Start MSSQL container' diff --git a/azure/opcache_variation_job.yml b/azure/opcache_variation_job.yml deleted file mode 100644 index 2d4cd2bd86844..0000000000000 --- a/azure/opcache_variation_job.yml +++ /dev/null @@ -1,88 +0,0 @@ -parameters: - configurationName: '' - configurationParameters: '' - runTestsParameters: '' - timeoutInMinutes: 60 - -jobs: - - job: ${{ parameters.configurationName }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - pool: - vmImage: 'ubuntu-20.04' - steps: - - template: mssql.yml - - template: apt.yml - - template: configure.yml - parameters: - configurationParameters: ${{ parameters.configurationParameters }} - - script: make -j$(/usr/bin/nproc) >/dev/null - displayName: 'Make Build' - - template: install.yml - - template: setup.yml - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'File Cache (prime shm)' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --file-cache-prime - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'File Cache (prime shm, use shm)' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --file-cache-use - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'File Cache (prime shm, use file)' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --file-cache-use - -d opcache.file_cache_only=1 - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'File Cache (prime file)' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --file-cache-prime - -d opcache.file_cache_only=1 - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'File Cache (prime file, use file)' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --file-cache-use - -d opcache.file_cache_only=1 - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'File Cache (prime file, use shm)' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --file-cache-use - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'Without interned strings' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - -d opcache.interned_strings_buffer=0 - - template: test.yml - parameters: - configurationName: ${{ parameters.configurationName }} - runTestsName: 'Preload' - runTestsParameters: >- - ${{ parameters.runTestsParameters }} - -d zend_extension=opcache.so - --preload diff --git a/azure/setup-slapd.sh b/azure/setup-slapd.sh deleted file mode 100755 index 7ea3cb33b3d0e..0000000000000 --- a/azure/setup-slapd.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/sh -set -ev - -# Create TLS certificate -sudo mkdir -p /etc/ldap/ssl - -alt_names() { - ( - ( - (hostname && hostname -a && hostname -A && hostname -f) | - xargs -n 1 | - sort -u | - sed -e 's/\(\S\+\)/DNS:\1/g' - ) && ( - (hostname -i && hostname -I && echo "127.0.0.1 ::1") | - xargs -n 1 | - sort -u | - sed -e 's/\(\S\+\)/IP:\1/g' - ) - ) | paste -d, -s -} - -sudo openssl req -newkey rsa:4096 -x509 -nodes -days 3650 \ - -out /etc/ldap/ssl/server.crt -keyout /etc/ldap/ssl/server.key \ - -subj "/C=US/ST=Arizona/L=Localhost/O=localhost/CN=localhost" \ - -addext "subjectAltName = `alt_names`" - -sudo chown -R openldap:openldap /etc/ldap/ssl - -# Display the TLS certificate (should be world readable) -openssl x509 -noout -text -in /etc/ldap/ssl/server.crt - -# Point to the certificate generated -if ! grep -q 'TLS_CACERT \/etc\/ldap\/ssl\/server.crt' /etc/ldap/ldap.conf; then - sudo sed -e 's|^\s*TLS_CACERT|# TLS_CACERT|' -i /etc/ldap/ldap.conf - echo 'TLS_CACERT /etc/ldap/ssl/server.crt' | sudo tee -a /etc/ldap/ldap.conf -fi - -# Configure LDAP protocols to serve. -sudo sed -e 's|^\s*SLAPD_SERVICES\s*=.*$|SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"|' -i /etc/default/slapd - -# Configure LDAP database. -DBDN=`sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(&(olcRootDN=*)(olcSuffix=*))' dn | grep -i '^dn:' | sed -e 's/^dn:\s*//'`; - -sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif - -sudo service slapd restart - -sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF -dn: $DBDN -changetype: modify -replace: olcSuffix -olcSuffix: dc=my-domain,dc=com -- -replace: olcRootDN -olcRootDN: cn=Manager,dc=my-domain,dc=com -- -replace: olcRootPW -olcRootPW: secret - -dn: cn=config -changetype: modify -add: olcTLSCACertificateFile -olcTLSCACertificateFile: /etc/ldap/ssl/server.crt -- -add: olcTLSCertificateFile -olcTLSCertificateFile: /etc/ldap/ssl/server.crt -- -add: olcTLSCertificateKeyFile -olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key -- -add: olcTLSVerifyClient -olcTLSVerifyClient: never -- -add: olcAuthzRegexp -olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com -- -replace: olcLogLevel -olcLogLevel: -1 - -dn: cn=module{0},cn=config -changetype: modify -add: olcModuleLoad -olcModuleLoad: sssvlv -- -add: olcModuleLoad -olcModuleLoad: ppolicy -- -add: olcModuleLoad -olcModuleLoad: dds -EOF - -sudo service slapd restart - -sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// << EOF -dn: olcOverlay=sssvlv,$DBDN -objectClass: olcOverlayConfig -objectClass: olcSssVlvConfig -olcOverlay: sssvlv -olcSssVlvMax: 10 -olcSssVlvMaxKeys: 5 - -dn: olcOverlay=ppolicy,$DBDN -objectClass: olcOverlayConfig -objectClass: olcPPolicyConfig -olcOverlay: ppolicy -### This would clutter our DIT and make tests to fail, while ppolicy does not -### seem to work as we expect (it does not seem to provide expected controls) -## olcPPolicyDefault: cn=default,ou=pwpolicies,dc=my-domain,dc=com -## olcPPolicyHashCleartext: FALSE -## olcPPolicyUseLockout: TRUE - -dn: olcOverlay=dds,$DBDN -objectClass: olcOverlayConfig -objectClass: olcDdsConfig -olcOverlay: dds -EOF - -sudo service slapd restart - -sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF -dn: $DBDN -changetype: modify -add: olcDbIndex -olcDbIndex: entryExpireTimestamp eq -EOF - -sudo service slapd restart - -ldapadd -H ldapi:/// -D cn=Manager,dc=my-domain,dc=com -w secret <" -Q "create login pdo_test with password='password', check_policy=off; create user pdo_test for login pdo_test; grant alter, control to pdo_test;" - sudo locale-gen de_DE - displayName: 'Setup' - - script: ./azure/setup-slapd.sh - displayName: 'Configure slapd' - - script: | - set -e - sudo cp ext/snmp/tests/snmpd.conf /etc/snmp - sudo cp ext/snmp/tests/bigtest /etc/snmp - sudo service snmpd restart - displayName: 'Configure snmpd' - - script: | - set -e - sudo groupadd -g 5000 vmail - sudo useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail - sudo cp ext/imap/tests/setup/dovecot.conf /etc/dovecot/dovecot.conf - sudo cp ext/imap/tests/setup/dovecotpass /etc/dovecot/dovecotpass - sudo service dovecot restart - displayName: 'Configure IMAP' - diff --git a/configure.ac b/configure.ac index 75021f30b983e..6d508b185b016 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.11-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.12],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER @@ -1211,6 +1211,7 @@ AS_CASE([$host_cpu], AS_CASE([$host_os], [darwin*], [fiber_os="mac"], [aix*|os400*], [fiber_os="aix"], + [freebsd*], [fiber_os="freebsd"], [fiber_os="other"] ) @@ -1234,6 +1235,15 @@ elif test "$fiber_os" = 'aix'; then # AIX uses a different calling convention (shared with non-_CALL_ELF Linux). # The AIX assembler isn't GNU, but the file is compatible. fiber_asm_file="${fiber_asm_file_prefix}_xcoff_gas" +elif test "$fiber_os" = 'freebsd'; then + case $fiber_cpu in + i386*) + fiber_asm="no" + ;; + *) + fiber_asm_file="${fiber_asm_file_prefix}_elf_gas" + ;; + esac elif test "$fiber_asm_file_prefix" != 'unknown'; then fiber_asm_file="${fiber_asm_file_prefix}_elf_gas" else diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 6e4c6247258e2..64ad3a0ba0867 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.15.3 on Sun Jun 26 17:34:01 2022 */ +/* Generated by re2c 0.15.3 on Wed Sep 14 10:36:03 2022 */ #line 1 "ext/date/lib/parse_date.re" /* * The MIT License (MIT) @@ -362,7 +362,7 @@ static timelib_error_message *alloc_error_message(timelib_error_message **messag return *messages + (*count)++; } -static void add_warning(Scanner *s, int error_code, char *error) +static void add_warning(Scanner *s, int error_code, const char *error) { timelib_error_message *message = alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count); @@ -372,7 +372,7 @@ static void add_warning(Scanner *s, int error_code, char *error) message->message = timelib_strdup(error); } -static void add_error(Scanner *s, int error_code, char *error) +static void add_error(Scanner *s, int error_code, const char *error) { timelib_error_message *message = alloc_error_message(&s->errors->error_messages, &s->errors->error_count); @@ -382,7 +382,7 @@ static void add_error(Scanner *s, int error_code, char *error) message->message = timelib_strdup(error); } -static void add_pbf_warning(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr) +static void add_pbf_warning(Scanner *s, int error_code, const char *error, const char *sptr, const char *cptr) { timelib_error_message *message = alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count); @@ -392,7 +392,7 @@ static void add_pbf_warning(Scanner *s, int error_code, char *error, const char message->message = timelib_strdup(error); } -static void add_pbf_error(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr) +static void add_pbf_error(Scanner *s, int error_code, const char *error, const char *sptr, const char *cptr) { timelib_error_message *message = alloc_error_message(&s->errors->error_messages, &s->errors->error_count); @@ -522,7 +522,6 @@ static timelib_sll timelib_get_frac_nr(const char **ptr) const char *begin, *end; char *str; double tmp_nr = TIMELIB_UNSET; - int len = 0; while ((**ptr != '.') && (**ptr != ':') && ((**ptr < '0') || (**ptr > '9'))) { if (**ptr == '\0') { @@ -533,7 +532,6 @@ static timelib_sll timelib_get_frac_nr(const char **ptr) begin = *ptr; while ((**ptr == '.') || (**ptr == ':') || ((**ptr >= '0') && (**ptr <= '9'))) { ++*ptr; - ++len; } end = *ptr; str = timelib_calloc(1, end - begin); @@ -954,11 +952,11 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) std: s->tok = cursor; s->len = 0; -#line 1085 "ext/date/lib/parse_date.re" +#line 1083 "ext/date/lib/parse_date.re" -#line 962 "" +#line 960 "" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -1096,7 +1094,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy3: YYDEBUG(3, *YYCURSOR); -#line 1819 "ext/date/lib/parse_date.re" +#line 1817 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("tzcorrection | tz"); @@ -1109,7 +1107,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_TIMEZONE; } -#line 1113 "" +#line 1111 "" yy4: YYDEBUG(4, *YYCURSOR); yych = *++YYCURSOR; @@ -1416,12 +1414,12 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy1483; yy12: YYDEBUG(12, *YYCURSOR); -#line 1914 "ext/date/lib/parse_date.re" +#line 1912 "ext/date/lib/parse_date.re" { add_error(s, TIMELIB_ERR_UNEXPECTED_CHARACTER, "Unexpected character"); goto std; } -#line 1425 "" +#line 1423 "" yy13: YYDEBUG(13, *YYCURSOR); yych = *++YYCURSOR; @@ -2665,11 +2663,11 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy54; yy49: YYDEBUG(49, *YYCURSOR); -#line 1903 "ext/date/lib/parse_date.re" +#line 1901 "ext/date/lib/parse_date.re" { goto std; } -#line 2673 "" +#line 2671 "" yy50: YYDEBUG(50, *YYCURSOR); yych = *++YYCURSOR; @@ -2678,12 +2676,12 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(51, *YYCURSOR); ++YYCURSOR; YYDEBUG(52, *YYCURSOR); -#line 1908 "ext/date/lib/parse_date.re" +#line 1906 "ext/date/lib/parse_date.re" { s->pos = cursor; s->line++; goto std; } -#line 2687 "" +#line 2685 "" yy53: YYDEBUG(53, *YYCURSOR); yych = *++YYCURSOR; @@ -3105,7 +3103,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych == 's') goto yy85; yy84: YYDEBUG(84, *YYCURSOR); -#line 1887 "ext/date/lib/parse_date.re" +#line 1885 "ext/date/lib/parse_date.re" { timelib_ull i; DEBUG_OUTPUT("relative"); @@ -3120,7 +3118,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 3124 "" +#line 3122 "" yy85: YYDEBUG(85, *YYCURSOR); yych = *++YYCURSOR; @@ -4129,7 +4127,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy219: YYDEBUG(219, *YYCURSOR); -#line 1750 "ext/date/lib/parse_date.re" +#line 1748 "ext/date/lib/parse_date.re" { const timelib_relunit* relunit; DEBUG_OUTPUT("daytext"); @@ -4146,7 +4144,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_WEEKDAY; } -#line 4150 "" +#line 4148 "" yy220: YYDEBUG(220, *YYCURSOR); yych = *++YYCURSOR; @@ -4692,7 +4690,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy248: YYDEBUG(248, *YYCURSOR); -#line 1809 "ext/date/lib/parse_date.re" +#line 1807 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("monthtext"); TIMELIB_INIT; @@ -4701,7 +4699,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 4705 "" +#line 4703 "" yy249: YYDEBUG(249, *YYCURSOR); ++YYCURSOR; @@ -4950,7 +4948,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) goto yy267; yy262: YYDEBUG(262, *YYCURSOR); -#line 1555 "ext/date/lib/parse_date.re" +#line 1553 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datetextual | datenoyear"); @@ -4963,7 +4961,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 4967 "" +#line 4965 "" yy263: YYDEBUG(263, *YYCURSOR); yyaccept = 6; @@ -5090,7 +5088,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy276: YYDEBUG(276, *YYCURSOR); -#line 1857 "ext/date/lib/parse_date.re" +#line 1855 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz"); @@ -5119,7 +5117,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_SHORTDATE_WITH_TIME; } -#line 5123 "" +#line 5121 "" yy277: YYDEBUG(277, *YYCURSOR); yyaccept = 7; @@ -5417,7 +5415,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(300, *YYCURSOR); ++YYCURSOR; YYDEBUG(301, *YYCURSOR); -#line 1833 "ext/date/lib/parse_date.re" +#line 1831 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12"); TIMELIB_INIT; @@ -5440,7 +5438,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_SHORTDATE_WITH_TIME; } -#line 5444 "" +#line 5442 "" yy302: YYDEBUG(302, *YYCURSOR); yych = *++YYCURSOR; @@ -6118,7 +6116,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(362, *YYCURSOR); ++YYCURSOR; YYDEBUG(363, *YYCURSOR); -#line 1527 "ext/date/lib/parse_date.re" +#line 1525 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datenoday"); @@ -6131,7 +6129,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 6135 "" +#line 6133 "" yy364: YYDEBUG(364, *YYCURSOR); yych = *++YYCURSOR; @@ -6362,7 +6360,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy372; yy371: YYDEBUG(371, *YYCURSOR); -#line 1671 "ext/date/lib/parse_date.re" +#line 1669 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pgtextshort"); @@ -6375,7 +6373,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 6379 "" +#line 6377 "" yy372: YYDEBUG(372, *YYCURSOR); yych = *++YYCURSOR; @@ -6957,7 +6955,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy398: YYDEBUG(398, *YYCURSOR); -#line 1729 "ext/date/lib/parse_date.re" +#line 1727 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("ago"); TIMELIB_INIT; @@ -6977,7 +6975,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_AGO; } -#line 6981 "" +#line 6979 "" yy399: YYDEBUG(399, *YYCURSOR); yyaccept = 5; @@ -8766,7 +8764,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) ++YYCURSOR; yy461: YYDEBUG(461, *YYCURSOR); -#line 1420 "ext/date/lib/parse_date.re" +#line 1418 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash"); TIMELIB_INIT; @@ -8777,7 +8775,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 8781 "" +#line 8779 "" yy462: YYDEBUG(462, *YYCURSOR); yych = *++YYCURSOR; @@ -8899,7 +8897,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(484, *YYCURSOR); ++YYCURSOR; YYDEBUG(485, *YYCURSOR); -#line 1446 "ext/date/lib/parse_date.re" +#line 1444 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("iso8601datex"); TIMELIB_INIT; @@ -8910,7 +8908,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 8914 "" +#line 8912 "" yy486: YYDEBUG(486, *YYCURSOR); yyaccept = 1; @@ -9664,7 +9662,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy509: YYDEBUG(509, *YYCURSOR); -#line 1569 "ext/date/lib/parse_date.re" +#line 1567 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenoyearrev"); TIMELIB_INIT; @@ -9675,7 +9673,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 9679 "" +#line 9677 "" yy510: YYDEBUG(510, *YYCURSOR); yyaccept = 9; @@ -9816,7 +9814,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(521, *YYCURSOR); ++YYCURSOR; YYDEBUG(522, *YYCURSOR); -#line 1273 "ext/date/lib/parse_date.re" +#line 1271 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12"); TIMELIB_INIT; @@ -9832,7 +9830,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_TIME12; } -#line 9836 "" +#line 9834 "" yy523: YYDEBUG(523, *YYCURSOR); yyaccept = 10; @@ -9845,7 +9843,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy524: YYDEBUG(524, *YYCURSOR); -#line 1310 "ext/date/lib/parse_date.re" +#line 1308 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("timetiny24 | timeshort24 | timelong24 | iso8601long"); @@ -9872,7 +9870,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_TIME24_WITH_ZONE; } -#line 9876 "" +#line 9874 "" yy525: YYDEBUG(525, *YYCURSOR); yyaccept = 10; @@ -10185,7 +10183,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(556, *YYCURSOR); ++YYCURSOR; YYDEBUG(557, *YYCURSOR); -#line 1290 "ext/date/lib/parse_date.re" +#line 1288 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("mssqltime"); TIMELIB_INIT; @@ -10204,7 +10202,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_TIME24_WITH_ZONE; } -#line 10208 "" +#line 10206 "" yy558: YYDEBUG(558, *YYCURSOR); yyaccept = 10; @@ -10310,7 +10308,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy574; yy568: YYDEBUG(568, *YYCURSOR); -#line 1486 "ext/date/lib/parse_date.re" +#line 1484 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datefull"); @@ -10324,7 +10322,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_FULL; } -#line 10328 "" +#line 10326 "" yy569: YYDEBUG(569, *YYCURSOR); yych = *++YYCURSOR; @@ -11060,7 +11058,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(639, *YYCURSOR); ++YYCURSOR; YYDEBUG(640, *YYCURSOR); -#line 1501 "ext/date/lib/parse_date.re" +#line 1499 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("pointed date YYYY"); TIMELIB_INIT; @@ -11071,7 +11069,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } -#line 11075 "" +#line 11073 "" yy641: YYDEBUG(641, *YYCURSOR); yyaccept = 10; @@ -11107,7 +11105,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy638; yy645: YYDEBUG(645, *YYCURSOR); -#line 1513 "ext/date/lib/parse_date.re" +#line 1511 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pointed date YY"); @@ -11120,7 +11118,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } -#line 11124 "" +#line 11122 "" yy646: YYDEBUG(646, *YYCURSOR); yyaccept = 10; @@ -11761,7 +11759,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy690: YYDEBUG(690, *YYCURSOR); -#line 1472 "ext/date/lib/parse_date.re" +#line 1470 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("gnudateshort"); @@ -11774,7 +11772,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 11778 "" +#line 11776 "" yy691: YYDEBUG(691, *YYCURSOR); yyaccept = 12; @@ -11880,7 +11878,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy700: YYDEBUG(700, *YYCURSOR); -#line 1404 "ext/date/lib/parse_date.re" +#line 1402 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("americanshort | american"); @@ -11895,7 +11893,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_AMERICAN; } -#line 11899 "" +#line 11897 "" yy701: YYDEBUG(701, *YYCURSOR); yyaccept = 13; @@ -12129,7 +12127,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= ':') goto yy737; yy734: YYDEBUG(734, *YYCURSOR); -#line 1699 "ext/date/lib/parse_date.re" +#line 1697 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("clf"); @@ -12149,7 +12147,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 12153 "" +#line 12151 "" yy735: YYDEBUG(735, *YYCURSOR); yyaccept = 14; @@ -12769,7 +12767,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy808: YYDEBUG(808, *YYCURSOR); -#line 1432 "ext/date/lib/parse_date.re" +#line 1430 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("iso8601date2"); @@ -12782,7 +12780,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 12786 "" +#line 12784 "" yy809: YYDEBUG(809, *YYCURSOR); yych = *++YYCURSOR; @@ -12821,7 +12819,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(815, *YYCURSOR); ++YYCURSOR; YYDEBUG(816, *YYCURSOR); -#line 1685 "ext/date/lib/parse_date.re" +#line 1683 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pgtextreverse"); @@ -12834,7 +12832,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 12838 "" +#line 12836 "" yy817: YYDEBUG(817, *YYCURSOR); yych = *++YYCURSOR; @@ -12999,7 +12997,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy828: YYDEBUG(828, *YYCURSOR); -#line 1720 "ext/date/lib/parse_date.re" +#line 1718 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("year4"); TIMELIB_INIT; @@ -13007,7 +13005,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 13011 "" +#line 13009 "" yy829: YYDEBUG(829, *YYCURSOR); yych = *++YYCURSOR; @@ -13212,7 +13210,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy838: YYDEBUG(838, *YYCURSOR); -#line 1541 "ext/date/lib/parse_date.re" +#line 1539 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("datenodayrev"); @@ -13225,7 +13223,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 13229 "" +#line 13227 "" yy839: YYDEBUG(839, *YYCURSOR); yych = *++YYCURSOR; @@ -13446,7 +13444,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '7') goto yy861; yy859: YYDEBUG(859, *YYCURSOR); -#line 1652 "ext/date/lib/parse_date.re" +#line 1650 "ext/date/lib/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweek"); @@ -13464,7 +13462,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 13468 "" +#line 13466 "" yy860: YYDEBUG(860, *YYCURSOR); yych = *++YYCURSOR; @@ -13474,7 +13472,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(861, *YYCURSOR); ++YYCURSOR; YYDEBUG(862, *YYCURSOR); -#line 1633 "ext/date/lib/parse_date.re" +#line 1631 "ext/date/lib/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweekday"); @@ -13492,7 +13490,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 13496 "" +#line 13494 "" yy863: YYDEBUG(863, *YYCURSOR); yych = *++YYCURSOR; @@ -13564,7 +13562,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy866: YYDEBUG(866, *YYCURSOR); -#line 1619 "ext/date/lib/parse_date.re" +#line 1617 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("pgydotd"); @@ -13577,7 +13575,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_PG_YEARDAY; } -#line 13581 "" +#line 13579 "" yy867: YYDEBUG(867, *YYCURSOR); yych = *++YYCURSOR; @@ -13680,7 +13678,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) ++YYCURSOR; yy887: YYDEBUG(887, *YYCURSOR); -#line 1593 "ext/date/lib/parse_date.re" +#line 1591 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif"); @@ -13705,7 +13703,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_XMLRPC_SOAP; } -#line 13709 "" +#line 13707 "" yy888: YYDEBUG(888, *YYCURSOR); yych = *++YYCURSOR; @@ -14001,7 +13999,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy893: YYDEBUG(893, *YYCURSOR); -#line 1581 "ext/date/lib/parse_date.re" +#line 1579 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenocolon"); TIMELIB_INIT; @@ -14012,7 +14010,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_DATE_NOCOLON; } -#line 14016 "" +#line 14014 "" yy894: YYDEBUG(894, *YYCURSOR); yych = *++YYCURSOR; @@ -14934,7 +14932,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1018: YYDEBUG(1018, *YYCURSOR); -#line 1458 "ext/date/lib/parse_date.re" +#line 1456 "ext/date/lib/parse_date.re" { int length = 0; DEBUG_OUTPUT("gnudateshorter"); @@ -14947,7 +14945,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 14951 "" +#line 14949 "" yy1019: YYDEBUG(1019, *YYCURSOR); yyaccept = 22; @@ -16155,7 +16153,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1127: YYDEBUG(1127, *YYCURSOR); -#line 1338 "ext/date/lib/parse_date.re" +#line 1336 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("gnunocolon"); TIMELIB_INIT; @@ -16177,7 +16175,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_GNU_NOCOLON; } -#line 16181 "" +#line 16179 "" yy1128: YYDEBUG(1128, *YYCURSOR); yych = *++YYCURSOR; @@ -16277,7 +16275,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1135: YYDEBUG(1135, *YYCURSOR); -#line 1384 "ext/date/lib/parse_date.re" +#line 1382 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("iso8601nocolon"); @@ -16296,7 +16294,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_ISO_NOCOLON; } -#line 16300 "" +#line 16298 "" yy1136: YYDEBUG(1136, *YYCURSOR); yyaccept = 25; @@ -17272,7 +17270,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1179: YYDEBUG(1179, *YYCURSOR); -#line 1792 "ext/date/lib/parse_date.re" +#line 1790 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior = 0; @@ -17288,7 +17286,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 17292 "" +#line 17290 "" yy1180: YYDEBUG(1180, *YYCURSOR); ++YYCURSOR; @@ -17354,7 +17352,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(1188, *YYCURSOR); ++YYCURSOR; YYDEBUG(1189, *YYCURSOR); -#line 1251 "ext/date/lib/parse_date.re" +#line 1249 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior = 0; @@ -17375,7 +17373,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_WEEK_DAY_OF_MONTH; } -#line 17379 "" +#line 17377 "" yy1190: YYDEBUG(1190, *YYCURSOR); yyaccept = 26; @@ -17515,7 +17513,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1206: YYDEBUG(1206, *YYCURSOR); -#line 1768 "ext/date/lib/parse_date.re" +#line 1766 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior = 0; @@ -17538,7 +17536,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 17542 "" +#line 17540 "" yy1207: YYDEBUG(1207, *YYCURSOR); yych = *++YYCURSOR; @@ -20487,7 +20485,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1388: YYDEBUG(1388, *YYCURSOR); -#line 1228 "ext/date/lib/parse_date.re" +#line 1226 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("backof | frontof"); TIMELIB_INIT; @@ -20509,7 +20507,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_LF_DAY_OF_MONTH; } -#line 20513 "" +#line 20511 "" yy1389: YYDEBUG(1389, *YYCURSOR); yyaccept = 28; @@ -20808,7 +20806,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) YYDEBUG(1410, *YYCURSOR); ++YYCURSOR; YYDEBUG(1411, *YYCURSOR); -#line 1211 "ext/date/lib/parse_date.re" +#line 1209 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("firstdayof | lastdayof"); TIMELIB_INIT; @@ -20824,7 +20822,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_LF_DAY_OF_MONTH; } -#line 20828 "" +#line 20826 "" yy1412: YYDEBUG(1412, *YYCURSOR); yyaccept = 1; @@ -22346,7 +22344,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy1483; yy1485: YYDEBUG(1485, *YYCURSOR); -#line 1145 "ext/date/lib/parse_date.re" +#line 1143 "ext/date/lib/parse_date.re" { timelib_ull i; @@ -22371,7 +22369,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 22375 "" +#line 22373 "" yy1486: YYDEBUG(1486, *YYCURSOR); ++YYCURSOR; @@ -22379,7 +22377,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) if (yych <= '9') goto yy1488; yy1487: YYDEBUG(1487, *YYCURSOR); -#line 1171 "ext/date/lib/parse_date.re" +#line 1169 "ext/date/lib/parse_date.re" { timelib_sll i; timelib_ull us; @@ -22418,7 +22416,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 22422 "" +#line 22420 "" yy1488: YYDEBUG(1488, *YYCURSOR); yych = *++YYCURSOR; @@ -22887,7 +22885,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) ++YYCURSOR; yy1524: YYDEBUG(1524, *YYCURSOR); -#line 1133 "ext/date/lib/parse_date.re" +#line 1131 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("tomorrow"); TIMELIB_INIT; @@ -22898,7 +22896,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 22902 "" +#line 22900 "" yy1525: YYDEBUG(1525, *YYCURSOR); yych = *++YYCURSOR; @@ -22933,7 +22931,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1527: YYDEBUG(1527, *YYCURSOR); -#line 1123 "ext/date/lib/parse_date.re" +#line 1121 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("midnight | today"); TIMELIB_INIT; @@ -22942,7 +22940,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 22946 "" +#line 22944 "" yy1528: YYDEBUG(1528, *YYCURSOR); yych = *++YYCURSOR; @@ -25037,7 +25035,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1612: YYDEBUG(1612, *YYCURSOR); -#line 1102 "ext/date/lib/parse_date.re" +#line 1100 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("now"); TIMELIB_INIT; @@ -25045,7 +25043,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 25049 "" +#line 25047 "" yy1613: YYDEBUG(1613, *YYCURSOR); yych = *++YYCURSOR; @@ -25184,7 +25182,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) } yy1620: YYDEBUG(1620, *YYCURSOR); -#line 1111 "ext/date/lib/parse_date.re" +#line 1109 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("noon"); TIMELIB_INIT; @@ -25195,7 +25193,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 25199 "" +#line 25197 "" yy1621: YYDEBUG(1621, *YYCURSOR); yyaccept = 1; @@ -25728,7 +25726,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) ++YYCURSOR; yy1643: YYDEBUG(1643, *YYCURSOR); -#line 1090 "ext/date/lib/parse_date.re" +#line 1088 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("yesterday"); TIMELIB_INIT; @@ -25739,7 +25737,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 25743 "" +#line 25741 "" yy1644: YYDEBUG(1644, *YYCURSOR); yyaccept = 1; @@ -25912,7 +25910,7 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) goto yy1643; } } -#line 1918 "ext/date/lib/parse_date.re" +#line 1916 "ext/date/lib/parse_date.re" } @@ -26609,15 +26607,18 @@ void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options) if (parsed->h == TIMELIB_UNSET) parsed->h = now->h != TIMELIB_UNSET ? now->h : 0; if (parsed->i == TIMELIB_UNSET) parsed->i = now->i != TIMELIB_UNSET ? now->i : 0; if (parsed->s == TIMELIB_UNSET) parsed->s = now->s != TIMELIB_UNSET ? now->s : 0; - if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0; - if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0; - if (!parsed->tz_abbr) { - parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL; - } if (!parsed->tz_info) { parsed->tz_info = now->tz_info ? (!(options & TIMELIB_NO_CLONE) ? timelib_tzinfo_clone(now->tz_info) : now->tz_info) : NULL; + + if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0; + if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0; + + if (!parsed->tz_abbr) { + parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL; + } } + if (parsed->zone_type == 0 && now->zone_type != 0) { parsed->zone_type = now->zone_type; /* parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL; @@ -26629,7 +26630,7 @@ void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options) */ } -char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst) +const char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst) { const timelib_tz_lookup_table *tp; diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index 11b0be0d4a6a2..403f98d5eae57 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -360,7 +360,7 @@ static timelib_error_message *alloc_error_message(timelib_error_message **messag return *messages + (*count)++; } -static void add_warning(Scanner *s, int error_code, char *error) +static void add_warning(Scanner *s, int error_code, const char *error) { timelib_error_message *message = alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count); @@ -370,7 +370,7 @@ static void add_warning(Scanner *s, int error_code, char *error) message->message = timelib_strdup(error); } -static void add_error(Scanner *s, int error_code, char *error) +static void add_error(Scanner *s, int error_code, const char *error) { timelib_error_message *message = alloc_error_message(&s->errors->error_messages, &s->errors->error_count); @@ -380,7 +380,7 @@ static void add_error(Scanner *s, int error_code, char *error) message->message = timelib_strdup(error); } -static void add_pbf_warning(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr) +static void add_pbf_warning(Scanner *s, int error_code, const char *error, const char *sptr, const char *cptr) { timelib_error_message *message = alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count); @@ -390,7 +390,7 @@ static void add_pbf_warning(Scanner *s, int error_code, char *error, const char message->message = timelib_strdup(error); } -static void add_pbf_error(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr) +static void add_pbf_error(Scanner *s, int error_code, const char *error, const char *sptr, const char *cptr) { timelib_error_message *message = alloc_error_message(&s->errors->error_messages, &s->errors->error_count); @@ -520,7 +520,6 @@ static timelib_sll timelib_get_frac_nr(const char **ptr) const char *begin, *end; char *str; double tmp_nr = TIMELIB_UNSET; - int len = 0; while ((**ptr != '.') && (**ptr != ':') && ((**ptr < '0') || (**ptr > '9'))) { if (**ptr == '\0') { @@ -531,7 +530,6 @@ static timelib_sll timelib_get_frac_nr(const char **ptr) begin = *ptr; while ((**ptr == '.') || (**ptr == ':') || ((**ptr >= '0') && (**ptr <= '9'))) { ++*ptr; - ++len; } end = *ptr; str = timelib_calloc(1, end - begin); @@ -2611,15 +2609,18 @@ void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options) if (parsed->h == TIMELIB_UNSET) parsed->h = now->h != TIMELIB_UNSET ? now->h : 0; if (parsed->i == TIMELIB_UNSET) parsed->i = now->i != TIMELIB_UNSET ? now->i : 0; if (parsed->s == TIMELIB_UNSET) parsed->s = now->s != TIMELIB_UNSET ? now->s : 0; - if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0; - if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0; - if (!parsed->tz_abbr) { - parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL; - } if (!parsed->tz_info) { parsed->tz_info = now->tz_info ? (!(options & TIMELIB_NO_CLONE) ? timelib_tzinfo_clone(now->tz_info) : now->tz_info) : NULL; + + if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0; + if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0; + + if (!parsed->tz_abbr) { + parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL; + } } + if (parsed->zone_type == 0 && now->zone_type != 0) { parsed->zone_type = now->zone_type; /* parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL; @@ -2631,7 +2632,7 @@ void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options) */ } -char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst) +const char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst) { const timelib_tz_lookup_table *tp; diff --git a/ext/date/lib/parse_iso_intervals.c b/ext/date/lib/parse_iso_intervals.c index 900443ae267bb..a467da3471fc9 100644 --- a/ext/date/lib/parse_iso_intervals.c +++ b/ext/date/lib/parse_iso_intervals.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.15.3 on Sun Jun 26 17:34:21 2022 */ +/* Generated by re2c 0.15.3 on Wed Sep 14 10:36:13 2022 */ #line 1 "ext/date/lib/parse_iso_intervals.re" /* * The MIT License (MIT) @@ -88,7 +88,7 @@ typedef struct _Scanner { int have_end_date; } Scanner; -static void add_error(Scanner *s, char *error) +static void add_error(Scanner *s, const char *error) { s->errors->error_count++; s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message)); diff --git a/ext/date/lib/parse_iso_intervals.re b/ext/date/lib/parse_iso_intervals.re index bd4015a323a39..2a394156f98df 100644 --- a/ext/date/lib/parse_iso_intervals.re +++ b/ext/date/lib/parse_iso_intervals.re @@ -86,7 +86,7 @@ typedef struct _Scanner { int have_end_date; } Scanner; -static void add_error(Scanner *s, char *error) +static void add_error(Scanner *s, const char *error) { s->errors->error_count++; s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message)); diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index f6868427980ad..dbdddd34f7b1d 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 202116 -#define TIMELIB_EXTENDED_VERSION 20211601 -#define TIMELIB_ASCII_VERSION "2021.16" +#define TIMELIB_VERSION 202117 +#define TIMELIB_EXTENDED_VERSION 20211701 +#define TIMELIB_ASCII_VERSION "2021.17" #include #include @@ -342,10 +342,10 @@ typedef struct _timelib_error_container { } timelib_error_container; typedef struct _timelib_tz_lookup_table { - char *name; + const char *name; int type; float gmtoffset; - char *full_tz_name; + const char *full_tz_name; } timelib_tz_lookup_table; typedef struct _timelib_tzdb_index_entry { @@ -354,7 +354,7 @@ typedef struct _timelib_tzdb_index_entry { } timelib_tzdb_index_entry; typedef struct _timelib_tzdb { - char *version; + const char *version; int index_size; const timelib_tzdb_index_entry *index; const unsigned char *data; @@ -583,7 +583,7 @@ void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options); * * The returned char* is not duplicated, and should not be freed. */ -char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst); +const char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst); /* Returns an array of known time zone abbreviations * diff --git a/ext/date/lib/timelib_private.h b/ext/date/lib/timelib_private.h index 2015a15dbf76f..65ec6b014b894 100644 --- a/ext/date/lib/timelib_private.h +++ b/ext/date/lib/timelib_private.h @@ -112,6 +112,20 @@ m = NULL; \ } +#if defined (__GNUC__) +# define TIMELIB_GNUC_CHECK_VERSION(major, minor) \ + ((__GNUC__ > (major)) || \ + ((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor)))) +#else +# define TIMELIB_GNUC_CHECK_VERSION(major, minor) 0 +#endif + +#if TIMELIB_GNUC_CHECK_VERSION(7, 0) +# define TIMELIB_BREAK_INTENTIONALLY_MISSING __attribute__ ((fallthrough)); +#else +# define TIMELIB_BREAK_INTENTIONALLY_MISSING +#endif + struct _ttinfo { int32_t offset; diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h index 8db0629127043..872a995898d6c 100644 --- a/ext/date/lib/timezonedb.h +++ b/ext/date/lib/timezonedb.h @@ -28,583 +28,583 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[596] = { { (char*) "Africa/Douala" , 0x001D0A }, { (char*) "Africa/El_Aaiun" , 0x001D99 }, { (char*) "Africa/Freetown" , 0x0024CB }, - { (char*) "Africa/Gaborone" , 0x002638 }, - { (char*) "Africa/Harare" , 0x0026F8 }, - { (char*) "Africa/Johannesburg" , 0x002787 }, - { (char*) "Africa/Juba" , 0x002851 }, - { (char*) "Africa/Kampala" , 0x002A27 }, - { (char*) "Africa/Khartoum" , 0x002AE9 }, - { (char*) "Africa/Kigali" , 0x002CBF }, - { (char*) "Africa/Kinshasa" , 0x002D4E }, - { (char*) "Africa/Lagos" , 0x002DF6 }, - { (char*) "Africa/Libreville" , 0x002EB6 }, - { (char*) "Africa/Lome" , 0x002F45 }, - { (char*) "Africa/Luanda" , 0x002FD3 }, - { (char*) "Africa/Lubumbashi" , 0x003071 }, - { (char*) "Africa/Lusaka" , 0x00312C }, - { (char*) "Africa/Malabo" , 0x0031BB }, - { (char*) "Africa/Maputo" , 0x00325D }, - { (char*) "Africa/Maseru" , 0x0032EC }, - { (char*) "Africa/Mbabane" , 0x003395 }, - { (char*) "Africa/Mogadishu" , 0x003426 }, - { (char*) "Africa/Monrovia" , 0x0034D3 }, - { (char*) "Africa/Nairobi" , 0x003583 }, - { (char*) "Africa/Ndjamena" , 0x00364E }, - { (char*) "Africa/Niamey" , 0x0036FA }, - { (char*) "Africa/Nouakchott" , 0x0037AF }, - { (char*) "Africa/Ouagadougou" , 0x003859 }, - { (char*) "Africa/Porto-Novo" , 0x0038E7 }, - { (char*) "Africa/Sao_Tome" , 0x003989 }, - { (char*) "Africa/Timbuktu" , 0x003A42 }, - { (char*) "Africa/Tripoli" , 0x003AEC }, - { (char*) "Africa/Tunis" , 0x003CA7 }, - { (char*) "Africa/Windhoek" , 0x003E74 }, - { (char*) "America/Adak" , 0x0040FE }, - { (char*) "America/Anchorage" , 0x0044E3 }, - { (char*) "America/Anguilla" , 0x0048D3 }, - { (char*) "America/Antigua" , 0x004961 }, - { (char*) "America/Araguaina" , 0x004A02 }, - { (char*) "America/Argentina/Buenos_Aires" , 0x004C67 }, - { (char*) "America/Argentina/Catamarca" , 0x004F4C }, - { (char*) "America/Argentina/ComodRivadavia" , 0x005237 }, - { (char*) "America/Argentina/Cordoba" , 0x005507 }, - { (char*) "America/Argentina/Jujuy" , 0x00580D }, - { (char*) "America/Argentina/La_Rioja" , 0x005AD5 }, - { (char*) "America/Argentina/Mendoza" , 0x005DBB }, - { (char*) "America/Argentina/Rio_Gallegos" , 0x006097 }, - { (char*) "America/Argentina/Salta" , 0x006376 }, - { (char*) "America/Argentina/San_Juan" , 0x00664A }, - { (char*) "America/Argentina/San_Luis" , 0x006930 }, - { (char*) "America/Argentina/Tucuman" , 0x006C16 }, - { (char*) "America/Argentina/Ushuaia" , 0x006F04 }, - { (char*) "America/Aruba" , 0x0071E9 }, - { (char*) "America/Asuncion" , 0x00728C }, - { (char*) "America/Atikokan" , 0x00760C }, - { (char*) "America/Atka" , 0x007719 }, - { (char*) "America/Bahia" , 0x007AEE }, - { (char*) "America/Bahia_Banderas" , 0x007DA9 }, - { (char*) "America/Barbados" , 0x007FE7 }, - { (char*) "America/Belem" , 0x008109 }, - { (char*) "America/Belize" , 0x0082B1 }, - { (char*) "America/Blanc-Sablon" , 0x0086D2 }, - { (char*) "America/Boa_Vista" , 0x0087C7 }, - { (char*) "America/Bogota" , 0x008988 }, - { (char*) "America/Boise" , 0x008A47 }, - { (char*) "America/Buenos_Aires" , 0x008E5A }, - { (char*) "America/Cambridge_Bay" , 0x00912A }, - { (char*) "America/Campo_Grande" , 0x00944A }, - { (char*) "America/Cancun" , 0x009820 }, - { (char*) "America/Caracas" , 0x009A61 }, - { (char*) "America/Catamarca" , 0x009B2B }, - { (char*) "America/Cayenne" , 0x009DFB }, - { (char*) "America/Cayman" , 0x009E9E }, - { (char*) "America/Chicago" , 0x009F3F }, - { (char*) "America/Chihuahua" , 0x00A639 }, - { (char*) "America/Coral_Harbour" , 0x00A7BF }, - { (char*) "America/Cordoba" , 0x00A8AB }, - { (char*) "America/Costa_Rica" , 0x00AB7B }, - { (char*) "America/Creston" , 0x00AC6F }, - { (char*) "America/Cuiaba" , 0x00AD2B }, - { (char*) "America/Curacao" , 0x00B0E8 }, - { (char*) "America/Danmarkshavn" , 0x00B18B }, - { (char*) "America/Dawson" , 0x00B370 }, - { (char*) "America/Dawson_Creek" , 0x00B793 }, - { (char*) "America/Denver" , 0x00BA6A }, - { (char*) "America/Detroit" , 0x00BE9D }, - { (char*) "America/Dominica" , 0x00C245 }, - { (char*) "America/Edmonton" , 0x00C2D3 }, - { (char*) "America/Eirunepe" , 0x00C6C6 }, - { (char*) "America/El_Salvador" , 0x00C895 }, - { (char*) "America/Ensenada" , 0x00C951 }, - { (char*) "America/Fort_Nelson" , 0x00CD5E }, - { (char*) "America/Fort_Wayne" , 0x00D326 }, - { (char*) "America/Fortaleza" , 0x00D545 }, - { (char*) "America/Glace_Bay" , 0x00D75B }, - { (char*) "America/Godthab" , 0x00DAF2 }, - { (char*) "America/Goose_Bay" , 0x00DCCF }, - { (char*) "America/Grand_Turk" , 0x00E327 }, - { (char*) "America/Grenada" , 0x00E688 }, - { (char*) "America/Guadeloupe" , 0x00E716 }, - { (char*) "America/Guatemala" , 0x00E7A4 }, - { (char*) "America/Guayaquil" , 0x00E884 }, - { (char*) "America/Guyana" , 0x00E955 }, - { (char*) "America/Halifax" , 0x00EA16 }, - { (char*) "America/Havana" , 0x00F0C8 }, - { (char*) "America/Hermosillo" , 0x00F531 }, - { (char*) "America/Indiana/Indianapolis" , 0x00F67A }, - { (char*) "America/Indiana/Knox" , 0x00F8B2 }, - { (char*) "America/Indiana/Marengo" , 0x00FCCB }, - { (char*) "America/Indiana/Petersburg" , 0x00FF25 }, - { (char*) "America/Indiana/Tell_City" , 0x0101EF }, - { (char*) "America/Indiana/Vevay" , 0x010419 }, - { (char*) "America/Indiana/Vincennes" , 0x0105B0 }, - { (char*) "America/Indiana/Winamac" , 0x010806 }, - { (char*) "America/Indianapolis" , 0x010A8C }, - { (char*) "America/Inuvik" , 0x010CAB }, - { (char*) "America/Iqaluit" , 0x010F88 }, - { (char*) "America/Jamaica" , 0x011296 }, - { (char*) "America/Jujuy" , 0x0113F5 }, - { (char*) "America/Juneau" , 0x0116B3 }, - { (char*) "America/Kentucky/Louisville" , 0x011A99 }, - { (char*) "America/Kentucky/Monticello" , 0x011F9D }, - { (char*) "America/Knox_IN" , 0x012389 }, - { (char*) "America/Kralendijk" , 0x01278D }, - { (char*) "America/La_Paz" , 0x012830 }, - { (char*) "America/Lima" , 0x0128E6 }, - { (char*) "America/Los_Angeles" , 0x012A0D }, - { (char*) "America/Louisville" , 0x012F2E }, - { (char*) "America/Lower_Princes" , 0x013414 }, - { (char*) "America/Maceio" , 0x0134B7 }, - { (char*) "America/Managua" , 0x0136C9 }, - { (char*) "America/Manaus" , 0x0137FC }, - { (char*) "America/Marigot" , 0x0139B3 }, - { (char*) "America/Martinique" , 0x013A41 }, - { (char*) "America/Matamoros" , 0x013AFF }, - { (char*) "America/Mazatlan" , 0x013CFE }, - { (char*) "America/Mendoza" , 0x013EAE }, - { (char*) "America/Menominee" , 0x01417E }, - { (char*) "America/Merida" , 0x01453E }, - { (char*) "America/Metlakatla" , 0x014699 }, - { (char*) "America/Mexico_City" , 0x01490F }, - { (char*) "America/Miquelon" , 0x014AC3 }, - { (char*) "America/Moncton" , 0x014CF5 }, - { (char*) "America/Monterrey" , 0x0152EE }, - { (char*) "America/Montevideo" , 0x015464 }, - { (char*) "America/Montreal" , 0x015839 }, - { (char*) "America/Montserrat" , 0x015EFA }, - { (char*) "America/Nassau" , 0x015F88 }, - { (char*) "America/New_York" , 0x016382 }, - { (char*) "America/Nipigon" , 0x016A72 }, - { (char*) "America/Nome" , 0x016DE2 }, - { (char*) "America/Noronha" , 0x0171CA }, - { (char*) "America/North_Dakota/Beulah" , 0x0173CA }, - { (char*) "America/North_Dakota/Center" , 0x0177FE }, - { (char*) "America/North_Dakota/New_Salem" , 0x017BFD }, - { (char*) "America/Nuuk" , 0x018002 }, - { (char*) "America/Ojinaga" , 0x0181F5 }, - { (char*) "America/Panama" , 0x01840D }, - { (char*) "America/Pangnirtung" , 0x0184AE }, - { (char*) "America/Paramaribo" , 0x0187D5 }, - { (char*) "America/Phoenix" , 0x01889C }, - { (char*) "America/Port-au-Prince" , 0x0189B5 }, - { (char*) "America/Port_of_Spain" , 0x018BF6 }, - { (char*) "America/Porto_Acre" , 0x018C84 }, - { (char*) "America/Porto_Velho" , 0x018E32 }, - { (char*) "America/Puerto_Rico" , 0x018FD0 }, - { (char*) "America/Punta_Arenas" , 0x01908D }, - { (char*) "America/Rainy_River" , 0x01956F }, - { (char*) "America/Rankin_Inlet" , 0x0198E0 }, - { (char*) "America/Recife" , 0x019BB6 }, - { (char*) "America/Regina" , 0x019DB0 }, - { (char*) "America/Resolute" , 0x01A04F }, - { (char*) "America/Rio_Branco" , 0x01A326 }, - { (char*) "America/Rosario" , 0x01A4D8 }, - { (char*) "America/Santa_Isabel" , 0x01A7A8 }, - { (char*) "America/Santarem" , 0x01ABB5 }, - { (char*) "America/Santiago" , 0x01AD65 }, - { (char*) "America/Santo_Domingo" , 0x01B2CD }, - { (char*) "America/Sao_Paulo" , 0x01B416 }, - { (char*) "America/Scoresbysund" , 0x01B810 }, - { (char*) "America/Shiprock" , 0x01BA18 }, - { (char*) "America/Sitka" , 0x01BE36 }, - { (char*) "America/St_Barthelemy" , 0x01C211 }, - { (char*) "America/St_Johns" , 0x01C29F }, - { (char*) "America/St_Kitts" , 0x01CA23 }, - { (char*) "America/St_Lucia" , 0x01CAB1 }, - { (char*) "America/St_Thomas" , 0x01CB52 }, - { (char*) "America/St_Vincent" , 0x01CBE0 }, - { (char*) "America/Swift_Current" , 0x01CC81 }, - { (char*) "America/Tegucigalpa" , 0x01CE0F }, - { (char*) "America/Thule" , 0x01CEDD }, - { (char*) "America/Thunder_Bay" , 0x01D0BE }, - { (char*) "America/Tijuana" , 0x01D455 }, - { (char*) "America/Toronto" , 0x01D883 }, - { (char*) "America/Tortola" , 0x01DF61 }, - { (char*) "America/Vancouver" , 0x01DFEF }, - { (char*) "America/Virgin" , 0x01E546 }, - { (char*) "America/Whitehorse" , 0x01E5D4 }, - { (char*) "America/Winnipeg" , 0x01E9F7 }, - { (char*) "America/Yakutat" , 0x01EF2E }, - { (char*) "America/Yellowknife" , 0x01F2FC }, - { (char*) "Antarctica/Casey" , 0x01F5F8 }, - { (char*) "Antarctica/Davis" , 0x01F6FC }, - { (char*) "Antarctica/DumontDUrville" , 0x01F7D2 }, - { (char*) "Antarctica/Macquarie" , 0x01F886 }, - { (char*) "Antarctica/Mawson" , 0x01FC72 }, - { (char*) "Antarctica/McMurdo" , 0x01FD1C }, - { (char*) "Antarctica/Palmer" , 0x02004E }, - { (char*) "Antarctica/Rothera" , 0x0203D7 }, - { (char*) "Antarctica/South_Pole" , 0x02046E }, - { (char*) "Antarctica/Syowa" , 0x02077A }, - { (char*) "Antarctica/Troll" , 0x020810 }, - { (char*) "Antarctica/Vostok" , 0x0208D2 }, - { (char*) "Arctic/Longyearbyen" , 0x020969 }, - { (char*) "Asia/Aden" , 0x020C19 }, - { (char*) "Asia/Almaty" , 0x020CAA }, - { (char*) "Asia/Amman" , 0x020F2E }, - { (char*) "Asia/Anadyr" , 0x0212D4 }, - { (char*) "Asia/Aqtau" , 0x0215DA }, - { (char*) "Asia/Aqtobe" , 0x021859 }, - { (char*) "Asia/Ashgabat" , 0x021AD9 }, - { (char*) "Asia/Ashkhabad" , 0x021C5C }, - { (char*) "Asia/Atyrau" , 0x021DDF }, - { (char*) "Asia/Baghdad" , 0x022068 }, - { (char*) "Asia/Bahrain" , 0x0222EA }, - { (char*) "Asia/Baku" , 0x0223A3 }, - { (char*) "Asia/Bangkok" , 0x022697 }, - { (char*) "Asia/Barnaul" , 0x02273B }, - { (char*) "Asia/Beirut" , 0x022A46 }, - { (char*) "Asia/Bishkek" , 0x022D2E }, - { (char*) "Asia/Brunei" , 0x022FA4 }, - { (char*) "Asia/Calcutta" , 0x02304A }, - { (char*) "Asia/Chita" , 0x023132 }, - { (char*) "Asia/Choibalsan" , 0x023440 }, - { (char*) "Asia/Chongqing" , 0x0236C9 }, - { (char*) "Asia/Chungking" , 0x02385E }, - { (char*) "Asia/Colombo" , 0x0239F3 }, - { (char*) "Asia/Dacca" , 0x023AF6 }, - { (char*) "Asia/Damascus" , 0x023BE9 }, - { (char*) "Asia/Dhaka" , 0x02400C }, - { (char*) "Asia/Dili" , 0x0240FF }, - { (char*) "Asia/Dubai" , 0x0241B5 }, - { (char*) "Asia/Dushanbe" , 0x024246 }, - { (char*) "Asia/Famagusta" , 0x0243C0 }, - { (char*) "Asia/Gaza" , 0x024787 }, - { (char*) "Asia/Harbin" , 0x024C75 }, - { (char*) "Asia/Hebron" , 0x024E0A }, - { (char*) "Asia/Ho_Chi_Minh" , 0x025309 }, - { (char*) "Asia/Hong_Kong" , 0x025401 }, - { (char*) "Asia/Hovd" , 0x025714 }, - { (char*) "Asia/Irkutsk" , 0x02599D }, - { (char*) "Asia/Istanbul" , 0x025CBB }, - { (char*) "Asia/Jakarta" , 0x026177 }, - { (char*) "Asia/Jayapura" , 0x026288 }, - { (char*) "Asia/Jerusalem" , 0x026375 }, - { (char*) "Asia/Kabul" , 0x0267B3 }, - { (char*) "Asia/Kamchatka" , 0x02685E }, - { (char*) "Asia/Karachi" , 0x026B53 }, - { (char*) "Asia/Kashgar" , 0x026C69 }, - { (char*) "Asia/Kathmandu" , 0x026CFA }, - { (char*) "Asia/Katmandu" , 0x026DA7 }, - { (char*) "Asia/Khandyga" , 0x026E54 }, - { (char*) "Asia/Kolkata" , 0x027185 }, - { (char*) "Asia/Krasnoyarsk" , 0x02726D }, - { (char*) "Asia/Kuala_Lumpur" , 0x027577 }, - { (char*) "Asia/Kuching" , 0x027697 }, - { (char*) "Asia/Kuwait" , 0x0277F1 }, - { (char*) "Asia/Macao" , 0x027882 }, - { (char*) "Asia/Macau" , 0x027BA5 }, - { (char*) "Asia/Magadan" , 0x027EC8 }, - { (char*) "Asia/Makassar" , 0x0281D3 }, - { (char*) "Asia/Manila" , 0x0282E6 }, - { (char*) "Asia/Muscat" , 0x0283E0 }, - { (char*) "Asia/Nicosia" , 0x028471 }, - { (char*) "Asia/Novokuznetsk" , 0x0286E5 }, - { (char*) "Asia/Novosibirsk" , 0x0289D8 }, - { (char*) "Asia/Omsk" , 0x028CE9 }, - { (char*) "Asia/Oral" , 0x028FE7 }, - { (char*) "Asia/Phnom_Penh" , 0x029273 }, - { (char*) "Asia/Pontianak" , 0x029347 }, - { (char*) "Asia/Pyongyang" , 0x029460 }, - { (char*) "Asia/Qatar" , 0x029523 }, - { (char*) "Asia/Qostanay" , 0x0295C7 }, - { (char*) "Asia/Qyzylorda" , 0x029854 }, - { (char*) "Asia/Rangoon" , 0x029AED }, - { (char*) "Asia/Riyadh" , 0x029BB4 }, - { (char*) "Asia/Saigon" , 0x029C45 }, - { (char*) "Asia/Sakhalin" , 0x029D3D }, - { (char*) "Asia/Samarkand" , 0x02A054 }, - { (char*) "Asia/Seoul" , 0x02A1DF }, - { (char*) "Asia/Shanghai" , 0x02A38A }, - { (char*) "Asia/Singapore" , 0x02A52B }, - { (char*) "Asia/Srednekolymsk" , 0x02A637 }, - { (char*) "Asia/Taipei" , 0x02A94B }, - { (char*) "Asia/Tashkent" , 0x02AB56 }, - { (char*) "Asia/Tbilisi" , 0x02ACE1 }, - { (char*) "Asia/Tehran" , 0x02AF62 }, - { (char*) "Asia/Tel_Aviv" , 0x02B29A }, - { (char*) "Asia/Thimbu" , 0x02B6D8 }, - { (char*) "Asia/Thimphu" , 0x02B77E }, - { (char*) "Asia/Tokyo" , 0x02B824 }, - { (char*) "Asia/Tomsk" , 0x02B905 }, - { (char*) "Asia/Ujung_Pandang" , 0x02BC10 }, - { (char*) "Asia/Ulaanbaatar" , 0x02BCDA }, - { (char*) "Asia/Ulan_Bator" , 0x02BF4D }, - { (char*) "Asia/Urumqi" , 0x02C1AB }, - { (char*) "Asia/Ust-Nera" , 0x02C249 }, - { (char*) "Asia/Vientiane" , 0x02C56C }, - { (char*) "Asia/Vladivostok" , 0x02C652 }, - { (char*) "Asia/Yakutsk" , 0x02C957 }, - { (char*) "Asia/Yangon" , 0x02CC5B }, - { (char*) "Asia/Yekaterinburg" , 0x02CD22 }, - { (char*) "Asia/Yerevan" , 0x02D034 }, - { (char*) "Atlantic/Azores" , 0x02D304 }, - { (char*) "Atlantic/Bermuda" , 0x02D8C3 }, - { (char*) "Atlantic/Canary" , 0x02DCCF }, - { (char*) "Atlantic/Cape_Verde" , 0x02DEC7 }, - { (char*) "Atlantic/Faeroe" , 0x02DF82 }, - { (char*) "Atlantic/Faroe" , 0x02E147 }, - { (char*) "Atlantic/Jan_Mayen" , 0x02E30C }, - { (char*) "Atlantic/Madeira" , 0x02E5BC }, - { (char*) "Atlantic/Reykjavik" , 0x02EB84 }, - { (char*) "Atlantic/South_Georgia" , 0x02EE81 }, - { (char*) "Atlantic/St_Helena" , 0x02EF11 }, - { (char*) "Atlantic/Stanley" , 0x02EFB2 }, - { (char*) "Australia/ACT" , 0x02F2D3 }, - { (char*) "Australia/Adelaide" , 0x02F667 }, - { (char*) "Australia/Brisbane" , 0x02FA1B }, - { (char*) "Australia/Broken_Hill" , 0x02FB5F }, - { (char*) "Australia/Canberra" , 0x02FF34 }, - { (char*) "Australia/Currie" , 0x0302C8 }, - { (char*) "Australia/Darwin" , 0x0306BF }, - { (char*) "Australia/Eucla" , 0x0307C7 }, - { (char*) "Australia/Hobart" , 0x030926 }, - { (char*) "Australia/LHI" , 0x030D25 }, - { (char*) "Australia/Lindeman" , 0x030FE5 }, - { (char*) "Australia/Lord_Howe" , 0x031155 }, - { (char*) "Australia/Melbourne" , 0x031425 }, - { (char*) "Australia/North" , 0x0317C1 }, - { (char*) "Australia/NSW" , 0x0318B7 }, - { (char*) "Australia/Perth" , 0x031C4B }, - { (char*) "Australia/Queensland" , 0x031DA7 }, - { (char*) "Australia/South" , 0x031ED4 }, - { (char*) "Australia/Sydney" , 0x032279 }, - { (char*) "Australia/Tasmania" , 0x032629 }, - { (char*) "Australia/Victoria" , 0x032A20 }, - { (char*) "Australia/West" , 0x032DB4 }, - { (char*) "Australia/Yancowinna" , 0x032EF2 }, - { (char*) "Brazil/Acre" , 0x0332AB }, - { (char*) "Brazil/DeNoronha" , 0x033459 }, - { (char*) "Brazil/East" , 0x033649 }, - { (char*) "Brazil/West" , 0x033A0D }, - { (char*) "Canada/Atlantic" , 0x033BB5 }, - { (char*) "Canada/Central" , 0x034249 }, - { (char*) "Canada/Eastern" , 0x034763 }, - { (char*) "Canada/Mountain" , 0x034E24 }, - { (char*) "Canada/Newfoundland" , 0x0351FA }, - { (char*) "Canada/Pacific" , 0x03595C }, - { (char*) "Canada/Saskatchewan" , 0x035E9A }, - { (char*) "Canada/Yukon" , 0x036124 }, - { (char*) "CET" , 0x036535 }, - { (char*) "Chile/Continental" , 0x0367AE }, - { (char*) "Chile/EasterIsland" , 0x036D04 }, - { (char*) "CST6CDT" , 0x0371A6 }, - { (char*) "Cuba" , 0x037569 }, - { (char*) "EET" , 0x0379D2 }, - { (char*) "Egypt" , 0x037BCF }, - { (char*) "Eire" , 0x0380D7 }, - { (char*) "EST" , 0x0386BB }, - { (char*) "EST5EDT" , 0x038736 }, - { (char*) "Etc/GMT" , 0x038AF9 }, - { (char*) "Etc/GMT+0" , 0x038B74 }, - { (char*) "Etc/GMT+1" , 0x038BEF }, - { (char*) "Etc/GMT+10" , 0x038C6C }, - { (char*) "Etc/GMT+11" , 0x038CEA }, - { (char*) "Etc/GMT+12" , 0x038D68 }, - { (char*) "Etc/GMT+2" , 0x038DE6 }, - { (char*) "Etc/GMT+3" , 0x038E63 }, - { (char*) "Etc/GMT+4" , 0x038EE0 }, - { (char*) "Etc/GMT+5" , 0x038F5D }, - { (char*) "Etc/GMT+6" , 0x038FDA }, - { (char*) "Etc/GMT+7" , 0x039057 }, - { (char*) "Etc/GMT+8" , 0x0390D4 }, - { (char*) "Etc/GMT+9" , 0x039151 }, - { (char*) "Etc/GMT-0" , 0x0391CE }, - { (char*) "Etc/GMT-1" , 0x039249 }, - { (char*) "Etc/GMT-10" , 0x0392C7 }, - { (char*) "Etc/GMT-11" , 0x039346 }, - { (char*) "Etc/GMT-12" , 0x0393C5 }, - { (char*) "Etc/GMT-13" , 0x039444 }, - { (char*) "Etc/GMT-14" , 0x0394C3 }, - { (char*) "Etc/GMT-2" , 0x039542 }, - { (char*) "Etc/GMT-3" , 0x0395C0 }, - { (char*) "Etc/GMT-4" , 0x03963E }, - { (char*) "Etc/GMT-5" , 0x0396BC }, - { (char*) "Etc/GMT-6" , 0x03973A }, - { (char*) "Etc/GMT-7" , 0x0397B8 }, - { (char*) "Etc/GMT-8" , 0x039836 }, - { (char*) "Etc/GMT-9" , 0x0398B4 }, - { (char*) "Etc/GMT0" , 0x039932 }, - { (char*) "Etc/Greenwich" , 0x0399AD }, - { (char*) "Etc/UCT" , 0x039A28 }, - { (char*) "Etc/Universal" , 0x039AA3 }, - { (char*) "Etc/UTC" , 0x039B1E }, - { (char*) "Etc/Zulu" , 0x039B99 }, - { (char*) "Europe/Amsterdam" , 0x039C14 }, - { (char*) "Europe/Andorra" , 0x03A04F }, - { (char*) "Europe/Astrakhan" , 0x03A1E0 }, - { (char*) "Europe/Athens" , 0x03A4D4 }, - { (char*) "Europe/Belfast" , 0x03A78A }, - { (char*) "Europe/Belgrade" , 0x03ADD5 }, - { (char*) "Europe/Berlin" , 0x03AFBF }, - { (char*) "Europe/Bratislava" , 0x03B2A0 }, - { (char*) "Europe/Brussels" , 0x03B57F }, - { (char*) "Europe/Bucharest" , 0x03B9DA }, - { (char*) "Europe/Budapest" , 0x03BC7B }, - { (char*) "Europe/Busingen" , 0x03BF85 }, - { (char*) "Europe/Chisinau" , 0x03C18A }, - { (char*) "Europe/Copenhagen" , 0x03C489 }, - { (char*) "Europe/Dublin" , 0x03C704 }, - { (char*) "Europe/Gibraltar" , 0x03CCE8 }, - { (char*) "Europe/Guernsey" , 0x03D1B8 }, - { (char*) "Europe/Helsinki" , 0x03D80F }, - { (char*) "Europe/Isle_of_Man" , 0x03D9FC }, - { (char*) "Europe/Istanbul" , 0x03E047 }, - { (char*) "Europe/Jersey" , 0x03E503 }, - { (char*) "Europe/Kaliningrad" , 0x03EB5A }, - { (char*) "Europe/Kiev" , 0x03EF02 }, - { (char*) "Europe/Kirov" , 0x03F13C }, - { (char*) "Europe/Kyiv" , 0x03F423 }, - { (char*) "Europe/Lisbon" , 0x03F671 }, - { (char*) "Europe/Ljubljana" , 0x03FC3E }, - { (char*) "Europe/London" , 0x03FE28 }, - { (char*) "Europe/Luxembourg" , 0x040473 }, - { (char*) "Europe/Madrid" , 0x0408BE }, - { (char*) "Europe/Malta" , 0x040C5B }, - { (char*) "Europe/Mariehamn" , 0x041007 }, - { (char*) "Europe/Minsk" , 0x0411F4 }, - { (char*) "Europe/Monaco" , 0x041528 }, - { (char*) "Europe/Moscow" , 0x04198E }, - { (char*) "Europe/Nicosia" , 0x041D3A }, - { (char*) "Europe/Oslo" , 0x041F9B }, - { (char*) "Europe/Paris" , 0x04224B }, - { (char*) "Europe/Podgorica" , 0x0426A8 }, - { (char*) "Europe/Prague" , 0x042892 }, - { (char*) "Europe/Riga" , 0x042B71 }, - { (char*) "Europe/Rome" , 0x042E33 }, - { (char*) "Europe/Samara" , 0x0431F2 }, - { (char*) "Europe/San_Marino" , 0x0434F3 }, - { (char*) "Europe/Sarajevo" , 0x0438B2 }, - { (char*) "Europe/Saratov" , 0x043A9C }, - { (char*) "Europe/Simferopol" , 0x043D8E }, - { (char*) "Europe/Skopje" , 0x044101 }, - { (char*) "Europe/Sofia" , 0x0442EB }, - { (char*) "Europe/Stockholm" , 0x044547 }, - { (char*) "Europe/Tallinn" , 0x044744 }, - { (char*) "Europe/Tirane" , 0x0449F3 }, - { (char*) "Europe/Tiraspol" , 0x044C5B }, - { (char*) "Europe/Ulyanovsk" , 0x044F5A }, - { (char*) "Europe/Uzhgorod" , 0x045270 }, - { (char*) "Europe/Vaduz" , 0x0454A5 }, - { (char*) "Europe/Vatican" , 0x04568F }, - { (char*) "Europe/Vienna" , 0x045A4E }, - { (char*) "Europe/Vilnius" , 0x045CEC }, - { (char*) "Europe/Volgograd" , 0x045F9C }, - { (char*) "Europe/Warsaw" , 0x046299 }, - { (char*) "Europe/Zagreb" , 0x046640 }, - { (char*) "Europe/Zaporozhye" , 0x04682A }, - { (char*) "Europe/Zurich" , 0x046A8A }, - { (char*) "Factory" , 0x046C87 }, - { (char*) "GB" , 0x046D04 }, - { (char*) "GB-Eire" , 0x04734F }, - { (char*) "GMT" , 0x04799A }, - { (char*) "GMT+0" , 0x047A15 }, - { (char*) "GMT-0" , 0x047A90 }, - { (char*) "GMT0" , 0x047B0B }, - { (char*) "Greenwich" , 0x047B86 }, - { (char*) "Hongkong" , 0x047C01 }, - { (char*) "HST" , 0x047F14 }, - { (char*) "Iceland" , 0x047F90 }, - { (char*) "Indian/Antananarivo" , 0x04828D }, - { (char*) "Indian/Chagos" , 0x048339 }, - { (char*) "Indian/Christmas" , 0x0483DD }, - { (char*) "Indian/Cocos" , 0x04846E }, - { (char*) "Indian/Comoro" , 0x048506 }, - { (char*) "Indian/Kerguelen" , 0x048595 }, - { (char*) "Indian/Mahe" , 0x048626 }, - { (char*) "Indian/Maldives" , 0x0486B7 }, - { (char*) "Indian/Mauritius" , 0x04875B }, - { (char*) "Indian/Mayotte" , 0x04881A }, - { (char*) "Indian/Reunion" , 0x0488A9 }, - { (char*) "Iran" , 0x04893A }, - { (char*) "Israel" , 0x048C72 }, - { (char*) "Jamaica" , 0x0490B0 }, - { (char*) "Japan" , 0x04920F }, - { (char*) "Kwajalein" , 0x0492F0 }, - { (char*) "Libya" , 0x0493D7 }, - { (char*) "MET" , 0x049592 }, - { (char*) "Mexico/BajaNorte" , 0x04980B }, - { (char*) "Mexico/BajaSur" , 0x049C18 }, - { (char*) "Mexico/General" , 0x049D93 }, - { (char*) "MST" , 0x049F3B }, - { (char*) "MST7MDT" , 0x049FB6 }, - { (char*) "Navajo" , 0x04A379 }, - { (char*) "NZ" , 0x04A797 }, - { (char*) "NZ-CHAT" , 0x04ABB6 }, - { (char*) "Pacific/Apia" , 0x04AEEA }, - { (char*) "Pacific/Auckland" , 0x04B08D }, - { (char*) "Pacific/Bougainville" , 0x04B4C4 }, - { (char*) "Pacific/Chatham" , 0x04B5A5 }, - { (char*) "Pacific/Chuuk" , 0x04B8E8 }, - { (char*) "Pacific/Easter" , 0x04B9C6 }, - { (char*) "Pacific/Efate" , 0x04BE75 }, - { (char*) "Pacific/Enderbury" , 0x04BFD7 }, - { (char*) "Pacific/Fakaofo" , 0x04C08F }, - { (char*) "Pacific/Fiji" , 0x04C134 }, - { (char*) "Pacific/Funafuti" , 0x04C2EC }, - { (char*) "Pacific/Galapagos" , 0x04C37E }, - { (char*) "Pacific/Gambier" , 0x04C44A }, - { (char*) "Pacific/Guadalcanal" , 0x04C4E9 }, - { (char*) "Pacific/Guam" , 0x04C57B }, - { (char*) "Pacific/Honolulu" , 0x04C6E5 }, - { (char*) "Pacific/Johnston" , 0x04C7D4 }, - { (char*) "Pacific/Kanton" , 0x04C8BD }, - { (char*) "Pacific/Kiritimati" , 0x04C984 }, - { (char*) "Pacific/Kosrae" , 0x04CA4A }, - { (char*) "Pacific/Kwajalein" , 0x04CB4E }, - { (char*) "Pacific/Majuro" , 0x04CC3E }, - { (char*) "Pacific/Marquesas" , 0x04CD41 }, - { (char*) "Pacific/Midway" , 0x04CDE9 }, - { (char*) "Pacific/Nauru" , 0x04CEA4 }, - { (char*) "Pacific/Niue" , 0x04CF67 }, - { (char*) "Pacific/Norfolk" , 0x04D00D }, - { (char*) "Pacific/Noumea" , 0x04D110 }, - { (char*) "Pacific/Pago_Pago" , 0x04D1E2 }, - { (char*) "Pacific/Palau" , 0x04D280 }, - { (char*) "Pacific/Pitcairn" , 0x04D320 }, - { (char*) "Pacific/Pohnpei" , 0x04D3C5 }, - { (char*) "Pacific/Ponape" , 0x04D4B5 }, - { (char*) "Pacific/Port_Moresby" , 0x04D597 }, - { (char*) "Pacific/Rarotonga" , 0x04D65A }, - { (char*) "Pacific/Saipan" , 0x04D7FC }, - { (char*) "Pacific/Samoa" , 0x04D8C3 }, - { (char*) "Pacific/Tahiti" , 0x04D961 }, - { (char*) "Pacific/Tarawa" , 0x04DA01 }, - { (char*) "Pacific/Tongatapu" , 0x04DAA2 }, - { (char*) "Pacific/Truk" , 0x04DB9B }, - { (char*) "Pacific/Wake" , 0x04DC6A }, - { (char*) "Pacific/Wallis" , 0x04DD07 }, - { (char*) "Pacific/Yap" , 0x04DD99 }, - { (char*) "Poland" , 0x04DE68 }, - { (char*) "Portugal" , 0x04E20F }, - { (char*) "PRC" , 0x04E7C9 }, - { (char*) "PST8PDT" , 0x04E95E }, - { (char*) "ROC" , 0x04ED21 }, - { (char*) "ROK" , 0x04EF2C }, - { (char*) "Singapore" , 0x04F0D7 }, - { (char*) "Turkey" , 0x04F1E3 }, - { (char*) "UCT" , 0x04F69F }, - { (char*) "Universal" , 0x04F71A }, - { (char*) "US/Alaska" , 0x04F795 }, - { (char*) "US/Aleutian" , 0x04FB72 }, - { (char*) "US/Arizona" , 0x04FF47 }, - { (char*) "US/Central" , 0x050043 }, - { (char*) "US/East-Indiana" , 0x050729 }, - { (char*) "US/Eastern" , 0x050948 }, - { (char*) "US/Hawaii" , 0x051024 }, - { (char*) "US/Indiana-Starke" , 0x05110D }, - { (char*) "US/Michigan" , 0x051511 }, - { (char*) "US/Mountain" , 0x0518A0 }, - { (char*) "US/Pacific" , 0x051CBE }, - { (char*) "US/Samoa" , 0x0521D8 }, - { (char*) "UTC" , 0x052276 }, - { (char*) "W-SU" , 0x0522F1 }, - { (char*) "WET" , 0x052689 }, - { (char*) "Zulu" , 0x052883 }, + { (char*) "Africa/Gaborone" , 0x00261B }, + { (char*) "Africa/Harare" , 0x0026DB }, + { (char*) "Africa/Johannesburg" , 0x00276A }, + { (char*) "Africa/Juba" , 0x002834 }, + { (char*) "Africa/Kampala" , 0x002A0A }, + { (char*) "Africa/Khartoum" , 0x002ACC }, + { (char*) "Africa/Kigali" , 0x002CA2 }, + { (char*) "Africa/Kinshasa" , 0x002D31 }, + { (char*) "Africa/Lagos" , 0x002DD9 }, + { (char*) "Africa/Libreville" , 0x002E99 }, + { (char*) "Africa/Lome" , 0x002F28 }, + { (char*) "Africa/Luanda" , 0x002FB6 }, + { (char*) "Africa/Lubumbashi" , 0x003054 }, + { (char*) "Africa/Lusaka" , 0x00310F }, + { (char*) "Africa/Malabo" , 0x00319E }, + { (char*) "Africa/Maputo" , 0x003240 }, + { (char*) "Africa/Maseru" , 0x0032CF }, + { (char*) "Africa/Mbabane" , 0x003378 }, + { (char*) "Africa/Mogadishu" , 0x003409 }, + { (char*) "Africa/Monrovia" , 0x0034B6 }, + { (char*) "Africa/Nairobi" , 0x003566 }, + { (char*) "Africa/Ndjamena" , 0x003631 }, + { (char*) "Africa/Niamey" , 0x0036DD }, + { (char*) "Africa/Nouakchott" , 0x003792 }, + { (char*) "Africa/Ouagadougou" , 0x00383C }, + { (char*) "Africa/Porto-Novo" , 0x0038CA }, + { (char*) "Africa/Sao_Tome" , 0x00396C }, + { (char*) "Africa/Timbuktu" , 0x003A25 }, + { (char*) "Africa/Tripoli" , 0x003ACF }, + { (char*) "Africa/Tunis" , 0x003C8A }, + { (char*) "Africa/Windhoek" , 0x003E57 }, + { (char*) "America/Adak" , 0x0040E1 }, + { (char*) "America/Anchorage" , 0x0044C6 }, + { (char*) "America/Anguilla" , 0x0048B6 }, + { (char*) "America/Antigua" , 0x004944 }, + { (char*) "America/Araguaina" , 0x0049E5 }, + { (char*) "America/Argentina/Buenos_Aires" , 0x004C4A }, + { (char*) "America/Argentina/Catamarca" , 0x004F2F }, + { (char*) "America/Argentina/ComodRivadavia" , 0x00521A }, + { (char*) "America/Argentina/Cordoba" , 0x0054EA }, + { (char*) "America/Argentina/Jujuy" , 0x0057F0 }, + { (char*) "America/Argentina/La_Rioja" , 0x005AB8 }, + { (char*) "America/Argentina/Mendoza" , 0x005D9E }, + { (char*) "America/Argentina/Rio_Gallegos" , 0x00607A }, + { (char*) "America/Argentina/Salta" , 0x006359 }, + { (char*) "America/Argentina/San_Juan" , 0x00662D }, + { (char*) "America/Argentina/San_Luis" , 0x006913 }, + { (char*) "America/Argentina/Tucuman" , 0x006BF9 }, + { (char*) "America/Argentina/Ushuaia" , 0x006EE7 }, + { (char*) "America/Aruba" , 0x0071CC }, + { (char*) "America/Asuncion" , 0x00726F }, + { (char*) "America/Atikokan" , 0x0075EF }, + { (char*) "America/Atka" , 0x0076FC }, + { (char*) "America/Bahia" , 0x007AD1 }, + { (char*) "America/Bahia_Banderas" , 0x007D8C }, + { (char*) "America/Barbados" , 0x007FCA }, + { (char*) "America/Belem" , 0x0080EC }, + { (char*) "America/Belize" , 0x008294 }, + { (char*) "America/Blanc-Sablon" , 0x0086B5 }, + { (char*) "America/Boa_Vista" , 0x0087AA }, + { (char*) "America/Bogota" , 0x00896B }, + { (char*) "America/Boise" , 0x008A2A }, + { (char*) "America/Buenos_Aires" , 0x008E3D }, + { (char*) "America/Cambridge_Bay" , 0x00910D }, + { (char*) "America/Campo_Grande" , 0x00942D }, + { (char*) "America/Cancun" , 0x009803 }, + { (char*) "America/Caracas" , 0x009A44 }, + { (char*) "America/Catamarca" , 0x009B0E }, + { (char*) "America/Cayenne" , 0x009DDE }, + { (char*) "America/Cayman" , 0x009E81 }, + { (char*) "America/Chicago" , 0x009F22 }, + { (char*) "America/Chihuahua" , 0x00A61C }, + { (char*) "America/Coral_Harbour" , 0x00A7A2 }, + { (char*) "America/Cordoba" , 0x00A88E }, + { (char*) "America/Costa_Rica" , 0x00AB5E }, + { (char*) "America/Creston" , 0x00AC52 }, + { (char*) "America/Cuiaba" , 0x00AD0E }, + { (char*) "America/Curacao" , 0x00B0CB }, + { (char*) "America/Danmarkshavn" , 0x00B16E }, + { (char*) "America/Dawson" , 0x00B353 }, + { (char*) "America/Dawson_Creek" , 0x00B776 }, + { (char*) "America/Denver" , 0x00BA4D }, + { (char*) "America/Detroit" , 0x00BE80 }, + { (char*) "America/Dominica" , 0x00C228 }, + { (char*) "America/Edmonton" , 0x00C2B6 }, + { (char*) "America/Eirunepe" , 0x00C6A9 }, + { (char*) "America/El_Salvador" , 0x00C878 }, + { (char*) "America/Ensenada" , 0x00C934 }, + { (char*) "America/Fort_Nelson" , 0x00CD41 }, + { (char*) "America/Fort_Wayne" , 0x00D309 }, + { (char*) "America/Fortaleza" , 0x00D528 }, + { (char*) "America/Glace_Bay" , 0x00D73E }, + { (char*) "America/Godthab" , 0x00DAD5 }, + { (char*) "America/Goose_Bay" , 0x00DCB2 }, + { (char*) "America/Grand_Turk" , 0x00E30A }, + { (char*) "America/Grenada" , 0x00E66B }, + { (char*) "America/Guadeloupe" , 0x00E6F9 }, + { (char*) "America/Guatemala" , 0x00E787 }, + { (char*) "America/Guayaquil" , 0x00E867 }, + { (char*) "America/Guyana" , 0x00E938 }, + { (char*) "America/Halifax" , 0x00E9F9 }, + { (char*) "America/Havana" , 0x00F0AB }, + { (char*) "America/Hermosillo" , 0x00F514 }, + { (char*) "America/Indiana/Indianapolis" , 0x00F65D }, + { (char*) "America/Indiana/Knox" , 0x00F895 }, + { (char*) "America/Indiana/Marengo" , 0x00FCAE }, + { (char*) "America/Indiana/Petersburg" , 0x00FF08 }, + { (char*) "America/Indiana/Tell_City" , 0x0101D2 }, + { (char*) "America/Indiana/Vevay" , 0x0103FC }, + { (char*) "America/Indiana/Vincennes" , 0x010593 }, + { (char*) "America/Indiana/Winamac" , 0x0107E9 }, + { (char*) "America/Indianapolis" , 0x010A6F }, + { (char*) "America/Inuvik" , 0x010C8E }, + { (char*) "America/Iqaluit" , 0x010F6B }, + { (char*) "America/Jamaica" , 0x011279 }, + { (char*) "America/Jujuy" , 0x0113D8 }, + { (char*) "America/Juneau" , 0x011696 }, + { (char*) "America/Kentucky/Louisville" , 0x011A7C }, + { (char*) "America/Kentucky/Monticello" , 0x011F80 }, + { (char*) "America/Knox_IN" , 0x01236C }, + { (char*) "America/Kralendijk" , 0x012770 }, + { (char*) "America/La_Paz" , 0x012813 }, + { (char*) "America/Lima" , 0x0128C9 }, + { (char*) "America/Los_Angeles" , 0x0129F0 }, + { (char*) "America/Louisville" , 0x012F11 }, + { (char*) "America/Lower_Princes" , 0x0133F7 }, + { (char*) "America/Maceio" , 0x01349A }, + { (char*) "America/Managua" , 0x0136AC }, + { (char*) "America/Manaus" , 0x0137DF }, + { (char*) "America/Marigot" , 0x013996 }, + { (char*) "America/Martinique" , 0x013A24 }, + { (char*) "America/Matamoros" , 0x013AE2 }, + { (char*) "America/Mazatlan" , 0x013CE1 }, + { (char*) "America/Mendoza" , 0x013E91 }, + { (char*) "America/Menominee" , 0x014161 }, + { (char*) "America/Merida" , 0x014521 }, + { (char*) "America/Metlakatla" , 0x01467C }, + { (char*) "America/Mexico_City" , 0x0148F2 }, + { (char*) "America/Miquelon" , 0x014AA6 }, + { (char*) "America/Moncton" , 0x014CD8 }, + { (char*) "America/Monterrey" , 0x0152D1 }, + { (char*) "America/Montevideo" , 0x015447 }, + { (char*) "America/Montreal" , 0x01581C }, + { (char*) "America/Montserrat" , 0x015EDD }, + { (char*) "America/Nassau" , 0x015F6B }, + { (char*) "America/New_York" , 0x016365 }, + { (char*) "America/Nipigon" , 0x016A55 }, + { (char*) "America/Nome" , 0x016DC5 }, + { (char*) "America/Noronha" , 0x0171AD }, + { (char*) "America/North_Dakota/Beulah" , 0x0173AD }, + { (char*) "America/North_Dakota/Center" , 0x0177E1 }, + { (char*) "America/North_Dakota/New_Salem" , 0x017BE0 }, + { (char*) "America/Nuuk" , 0x017FE5 }, + { (char*) "America/Ojinaga" , 0x0181D8 }, + { (char*) "America/Panama" , 0x0183F0 }, + { (char*) "America/Pangnirtung" , 0x018491 }, + { (char*) "America/Paramaribo" , 0x0187B8 }, + { (char*) "America/Phoenix" , 0x01887F }, + { (char*) "America/Port-au-Prince" , 0x018998 }, + { (char*) "America/Port_of_Spain" , 0x018BD9 }, + { (char*) "America/Porto_Acre" , 0x018C67 }, + { (char*) "America/Porto_Velho" , 0x018E15 }, + { (char*) "America/Puerto_Rico" , 0x018FB3 }, + { (char*) "America/Punta_Arenas" , 0x019070 }, + { (char*) "America/Rainy_River" , 0x019552 }, + { (char*) "America/Rankin_Inlet" , 0x0198C3 }, + { (char*) "America/Recife" , 0x019B99 }, + { (char*) "America/Regina" , 0x019D93 }, + { (char*) "America/Resolute" , 0x01A032 }, + { (char*) "America/Rio_Branco" , 0x01A309 }, + { (char*) "America/Rosario" , 0x01A4BB }, + { (char*) "America/Santa_Isabel" , 0x01A78B }, + { (char*) "America/Santarem" , 0x01AB98 }, + { (char*) "America/Santiago" , 0x01AD48 }, + { (char*) "America/Santo_Domingo" , 0x01B2B0 }, + { (char*) "America/Sao_Paulo" , 0x01B3F9 }, + { (char*) "America/Scoresbysund" , 0x01B7F3 }, + { (char*) "America/Shiprock" , 0x01B9FB }, + { (char*) "America/Sitka" , 0x01BE19 }, + { (char*) "America/St_Barthelemy" , 0x01C1F4 }, + { (char*) "America/St_Johns" , 0x01C282 }, + { (char*) "America/St_Kitts" , 0x01CA06 }, + { (char*) "America/St_Lucia" , 0x01CA94 }, + { (char*) "America/St_Thomas" , 0x01CB35 }, + { (char*) "America/St_Vincent" , 0x01CBC3 }, + { (char*) "America/Swift_Current" , 0x01CC64 }, + { (char*) "America/Tegucigalpa" , 0x01CDF2 }, + { (char*) "America/Thule" , 0x01CEC0 }, + { (char*) "America/Thunder_Bay" , 0x01D0A1 }, + { (char*) "America/Tijuana" , 0x01D438 }, + { (char*) "America/Toronto" , 0x01D866 }, + { (char*) "America/Tortola" , 0x01DF44 }, + { (char*) "America/Vancouver" , 0x01DFD2 }, + { (char*) "America/Virgin" , 0x01E529 }, + { (char*) "America/Whitehorse" , 0x01E5B7 }, + { (char*) "America/Winnipeg" , 0x01E9DA }, + { (char*) "America/Yakutat" , 0x01EF11 }, + { (char*) "America/Yellowknife" , 0x01F2DF }, + { (char*) "Antarctica/Casey" , 0x01F5DB }, + { (char*) "Antarctica/Davis" , 0x01F6DF }, + { (char*) "Antarctica/DumontDUrville" , 0x01F7B5 }, + { (char*) "Antarctica/Macquarie" , 0x01F869 }, + { (char*) "Antarctica/Mawson" , 0x01FC55 }, + { (char*) "Antarctica/McMurdo" , 0x01FCFF }, + { (char*) "Antarctica/Palmer" , 0x020031 }, + { (char*) "Antarctica/Rothera" , 0x0203BA }, + { (char*) "Antarctica/South_Pole" , 0x020451 }, + { (char*) "Antarctica/Syowa" , 0x02075D }, + { (char*) "Antarctica/Troll" , 0x0207F3 }, + { (char*) "Antarctica/Vostok" , 0x0208B5 }, + { (char*) "Arctic/Longyearbyen" , 0x02094C }, + { (char*) "Asia/Aden" , 0x020BFC }, + { (char*) "Asia/Almaty" , 0x020C8D }, + { (char*) "Asia/Amman" , 0x020F11 }, + { (char*) "Asia/Anadyr" , 0x0212B7 }, + { (char*) "Asia/Aqtau" , 0x0215BD }, + { (char*) "Asia/Aqtobe" , 0x02183C }, + { (char*) "Asia/Ashgabat" , 0x021ABC }, + { (char*) "Asia/Ashkhabad" , 0x021C3F }, + { (char*) "Asia/Atyrau" , 0x021DC2 }, + { (char*) "Asia/Baghdad" , 0x02204B }, + { (char*) "Asia/Bahrain" , 0x0222CD }, + { (char*) "Asia/Baku" , 0x022386 }, + { (char*) "Asia/Bangkok" , 0x02267A }, + { (char*) "Asia/Barnaul" , 0x02271E }, + { (char*) "Asia/Beirut" , 0x022A29 }, + { (char*) "Asia/Bishkek" , 0x022D11 }, + { (char*) "Asia/Brunei" , 0x022F87 }, + { (char*) "Asia/Calcutta" , 0x02302D }, + { (char*) "Asia/Chita" , 0x023115 }, + { (char*) "Asia/Choibalsan" , 0x023423 }, + { (char*) "Asia/Chongqing" , 0x0236AC }, + { (char*) "Asia/Chungking" , 0x023841 }, + { (char*) "Asia/Colombo" , 0x0239D6 }, + { (char*) "Asia/Dacca" , 0x023AD9 }, + { (char*) "Asia/Damascus" , 0x023BCC }, + { (char*) "Asia/Dhaka" , 0x023FEF }, + { (char*) "Asia/Dili" , 0x0240E2 }, + { (char*) "Asia/Dubai" , 0x024198 }, + { (char*) "Asia/Dushanbe" , 0x024229 }, + { (char*) "Asia/Famagusta" , 0x0243A3 }, + { (char*) "Asia/Gaza" , 0x02476A }, + { (char*) "Asia/Harbin" , 0x024C6A }, + { (char*) "Asia/Hebron" , 0x024DFF }, + { (char*) "Asia/Ho_Chi_Minh" , 0x025310 }, + { (char*) "Asia/Hong_Kong" , 0x025408 }, + { (char*) "Asia/Hovd" , 0x02571B }, + { (char*) "Asia/Irkutsk" , 0x0259A4 }, + { (char*) "Asia/Istanbul" , 0x025CC2 }, + { (char*) "Asia/Jakarta" , 0x02617E }, + { (char*) "Asia/Jayapura" , 0x02628F }, + { (char*) "Asia/Jerusalem" , 0x02637C }, + { (char*) "Asia/Kabul" , 0x0267BA }, + { (char*) "Asia/Kamchatka" , 0x026865 }, + { (char*) "Asia/Karachi" , 0x026B5A }, + { (char*) "Asia/Kashgar" , 0x026C70 }, + { (char*) "Asia/Kathmandu" , 0x026D01 }, + { (char*) "Asia/Katmandu" , 0x026DAE }, + { (char*) "Asia/Khandyga" , 0x026E5B }, + { (char*) "Asia/Kolkata" , 0x02718C }, + { (char*) "Asia/Krasnoyarsk" , 0x027274 }, + { (char*) "Asia/Kuala_Lumpur" , 0x02757E }, + { (char*) "Asia/Kuching" , 0x02769E }, + { (char*) "Asia/Kuwait" , 0x0277F8 }, + { (char*) "Asia/Macao" , 0x027889 }, + { (char*) "Asia/Macau" , 0x027BAC }, + { (char*) "Asia/Magadan" , 0x027ECF }, + { (char*) "Asia/Makassar" , 0x0281DA }, + { (char*) "Asia/Manila" , 0x0282ED }, + { (char*) "Asia/Muscat" , 0x0283E7 }, + { (char*) "Asia/Nicosia" , 0x028478 }, + { (char*) "Asia/Novokuznetsk" , 0x0286EC }, + { (char*) "Asia/Novosibirsk" , 0x0289DF }, + { (char*) "Asia/Omsk" , 0x028CF0 }, + { (char*) "Asia/Oral" , 0x028FEE }, + { (char*) "Asia/Phnom_Penh" , 0x02927A }, + { (char*) "Asia/Pontianak" , 0x02934E }, + { (char*) "Asia/Pyongyang" , 0x029467 }, + { (char*) "Asia/Qatar" , 0x02952A }, + { (char*) "Asia/Qostanay" , 0x0295CE }, + { (char*) "Asia/Qyzylorda" , 0x02985B }, + { (char*) "Asia/Rangoon" , 0x029AF4 }, + { (char*) "Asia/Riyadh" , 0x029BBB }, + { (char*) "Asia/Saigon" , 0x029C4C }, + { (char*) "Asia/Sakhalin" , 0x029D44 }, + { (char*) "Asia/Samarkand" , 0x02A05B }, + { (char*) "Asia/Seoul" , 0x02A1E6 }, + { (char*) "Asia/Shanghai" , 0x02A391 }, + { (char*) "Asia/Singapore" , 0x02A532 }, + { (char*) "Asia/Srednekolymsk" , 0x02A63E }, + { (char*) "Asia/Taipei" , 0x02A952 }, + { (char*) "Asia/Tashkent" , 0x02AB5D }, + { (char*) "Asia/Tbilisi" , 0x02ACE8 }, + { (char*) "Asia/Tehran" , 0x02AF69 }, + { (char*) "Asia/Tel_Aviv" , 0x02B2A1 }, + { (char*) "Asia/Thimbu" , 0x02B6DF }, + { (char*) "Asia/Thimphu" , 0x02B785 }, + { (char*) "Asia/Tokyo" , 0x02B82B }, + { (char*) "Asia/Tomsk" , 0x02B90C }, + { (char*) "Asia/Ujung_Pandang" , 0x02BC17 }, + { (char*) "Asia/Ulaanbaatar" , 0x02BCE1 }, + { (char*) "Asia/Ulan_Bator" , 0x02BF54 }, + { (char*) "Asia/Urumqi" , 0x02C1B2 }, + { (char*) "Asia/Ust-Nera" , 0x02C250 }, + { (char*) "Asia/Vientiane" , 0x02C573 }, + { (char*) "Asia/Vladivostok" , 0x02C659 }, + { (char*) "Asia/Yakutsk" , 0x02C95E }, + { (char*) "Asia/Yangon" , 0x02CC62 }, + { (char*) "Asia/Yekaterinburg" , 0x02CD29 }, + { (char*) "Asia/Yerevan" , 0x02D03B }, + { (char*) "Atlantic/Azores" , 0x02D30B }, + { (char*) "Atlantic/Bermuda" , 0x02D8CA }, + { (char*) "Atlantic/Canary" , 0x02DCD6 }, + { (char*) "Atlantic/Cape_Verde" , 0x02DECE }, + { (char*) "Atlantic/Faeroe" , 0x02DF89 }, + { (char*) "Atlantic/Faroe" , 0x02E14E }, + { (char*) "Atlantic/Jan_Mayen" , 0x02E313 }, + { (char*) "Atlantic/Madeira" , 0x02E5C3 }, + { (char*) "Atlantic/Reykjavik" , 0x02EB8B }, + { (char*) "Atlantic/South_Georgia" , 0x02EE88 }, + { (char*) "Atlantic/St_Helena" , 0x02EF18 }, + { (char*) "Atlantic/Stanley" , 0x02EFB9 }, + { (char*) "Australia/ACT" , 0x02F2DA }, + { (char*) "Australia/Adelaide" , 0x02F66E }, + { (char*) "Australia/Brisbane" , 0x02FA22 }, + { (char*) "Australia/Broken_Hill" , 0x02FB66 }, + { (char*) "Australia/Canberra" , 0x02FF3B }, + { (char*) "Australia/Currie" , 0x0302CF }, + { (char*) "Australia/Darwin" , 0x0306C6 }, + { (char*) "Australia/Eucla" , 0x0307CE }, + { (char*) "Australia/Hobart" , 0x03092D }, + { (char*) "Australia/LHI" , 0x030D2C }, + { (char*) "Australia/Lindeman" , 0x030FEC }, + { (char*) "Australia/Lord_Howe" , 0x03115C }, + { (char*) "Australia/Melbourne" , 0x03142C }, + { (char*) "Australia/North" , 0x0317C8 }, + { (char*) "Australia/NSW" , 0x0318BE }, + { (char*) "Australia/Perth" , 0x031C52 }, + { (char*) "Australia/Queensland" , 0x031DAE }, + { (char*) "Australia/South" , 0x031EDB }, + { (char*) "Australia/Sydney" , 0x032280 }, + { (char*) "Australia/Tasmania" , 0x032630 }, + { (char*) "Australia/Victoria" , 0x032A27 }, + { (char*) "Australia/West" , 0x032DBB }, + { (char*) "Australia/Yancowinna" , 0x032EF9 }, + { (char*) "Brazil/Acre" , 0x0332B2 }, + { (char*) "Brazil/DeNoronha" , 0x033460 }, + { (char*) "Brazil/East" , 0x033650 }, + { (char*) "Brazil/West" , 0x033A14 }, + { (char*) "Canada/Atlantic" , 0x033BBC }, + { (char*) "Canada/Central" , 0x034250 }, + { (char*) "Canada/Eastern" , 0x03476A }, + { (char*) "Canada/Mountain" , 0x034E2B }, + { (char*) "Canada/Newfoundland" , 0x035201 }, + { (char*) "Canada/Pacific" , 0x035963 }, + { (char*) "Canada/Saskatchewan" , 0x035EA1 }, + { (char*) "Canada/Yukon" , 0x03612B }, + { (char*) "CET" , 0x03653C }, + { (char*) "Chile/Continental" , 0x0367B5 }, + { (char*) "Chile/EasterIsland" , 0x036D0B }, + { (char*) "CST6CDT" , 0x0371AD }, + { (char*) "Cuba" , 0x037570 }, + { (char*) "EET" , 0x0379D9 }, + { (char*) "Egypt" , 0x037BD6 }, + { (char*) "Eire" , 0x0380DE }, + { (char*) "EST" , 0x0386C2 }, + { (char*) "EST5EDT" , 0x03873D }, + { (char*) "Etc/GMT" , 0x038B00 }, + { (char*) "Etc/GMT+0" , 0x038B7B }, + { (char*) "Etc/GMT+1" , 0x038BF6 }, + { (char*) "Etc/GMT+10" , 0x038C73 }, + { (char*) "Etc/GMT+11" , 0x038CF1 }, + { (char*) "Etc/GMT+12" , 0x038D6F }, + { (char*) "Etc/GMT+2" , 0x038DED }, + { (char*) "Etc/GMT+3" , 0x038E6A }, + { (char*) "Etc/GMT+4" , 0x038EE7 }, + { (char*) "Etc/GMT+5" , 0x038F64 }, + { (char*) "Etc/GMT+6" , 0x038FE1 }, + { (char*) "Etc/GMT+7" , 0x03905E }, + { (char*) "Etc/GMT+8" , 0x0390DB }, + { (char*) "Etc/GMT+9" , 0x039158 }, + { (char*) "Etc/GMT-0" , 0x0391D5 }, + { (char*) "Etc/GMT-1" , 0x039250 }, + { (char*) "Etc/GMT-10" , 0x0392CE }, + { (char*) "Etc/GMT-11" , 0x03934D }, + { (char*) "Etc/GMT-12" , 0x0393CC }, + { (char*) "Etc/GMT-13" , 0x03944B }, + { (char*) "Etc/GMT-14" , 0x0394CA }, + { (char*) "Etc/GMT-2" , 0x039549 }, + { (char*) "Etc/GMT-3" , 0x0395C7 }, + { (char*) "Etc/GMT-4" , 0x039645 }, + { (char*) "Etc/GMT-5" , 0x0396C3 }, + { (char*) "Etc/GMT-6" , 0x039741 }, + { (char*) "Etc/GMT-7" , 0x0397BF }, + { (char*) "Etc/GMT-8" , 0x03983D }, + { (char*) "Etc/GMT-9" , 0x0398BB }, + { (char*) "Etc/GMT0" , 0x039939 }, + { (char*) "Etc/Greenwich" , 0x0399B4 }, + { (char*) "Etc/UCT" , 0x039A2F }, + { (char*) "Etc/Universal" , 0x039AAA }, + { (char*) "Etc/UTC" , 0x039B25 }, + { (char*) "Etc/Zulu" , 0x039BA0 }, + { (char*) "Europe/Amsterdam" , 0x039C1B }, + { (char*) "Europe/Andorra" , 0x03A056 }, + { (char*) "Europe/Astrakhan" , 0x03A1E7 }, + { (char*) "Europe/Athens" , 0x03A4DB }, + { (char*) "Europe/Belfast" , 0x03A791 }, + { (char*) "Europe/Belgrade" , 0x03ADDC }, + { (char*) "Europe/Berlin" , 0x03AFC6 }, + { (char*) "Europe/Bratislava" , 0x03B2A7 }, + { (char*) "Europe/Brussels" , 0x03B586 }, + { (char*) "Europe/Bucharest" , 0x03B9E1 }, + { (char*) "Europe/Budapest" , 0x03BC82 }, + { (char*) "Europe/Busingen" , 0x03BF8C }, + { (char*) "Europe/Chisinau" , 0x03C191 }, + { (char*) "Europe/Copenhagen" , 0x03C490 }, + { (char*) "Europe/Dublin" , 0x03C70B }, + { (char*) "Europe/Gibraltar" , 0x03CCEF }, + { (char*) "Europe/Guernsey" , 0x03D1BF }, + { (char*) "Europe/Helsinki" , 0x03D816 }, + { (char*) "Europe/Isle_of_Man" , 0x03DA03 }, + { (char*) "Europe/Istanbul" , 0x03E04E }, + { (char*) "Europe/Jersey" , 0x03E50A }, + { (char*) "Europe/Kaliningrad" , 0x03EB61 }, + { (char*) "Europe/Kiev" , 0x03EF09 }, + { (char*) "Europe/Kirov" , 0x03F143 }, + { (char*) "Europe/Kyiv" , 0x03F42A }, + { (char*) "Europe/Lisbon" , 0x03F678 }, + { (char*) "Europe/Ljubljana" , 0x03FC45 }, + { (char*) "Europe/London" , 0x03FE2F }, + { (char*) "Europe/Luxembourg" , 0x04047A }, + { (char*) "Europe/Madrid" , 0x0408C5 }, + { (char*) "Europe/Malta" , 0x040C62 }, + { (char*) "Europe/Mariehamn" , 0x04100E }, + { (char*) "Europe/Minsk" , 0x0411FB }, + { (char*) "Europe/Monaco" , 0x04152F }, + { (char*) "Europe/Moscow" , 0x041995 }, + { (char*) "Europe/Nicosia" , 0x041D41 }, + { (char*) "Europe/Oslo" , 0x041FA2 }, + { (char*) "Europe/Paris" , 0x042252 }, + { (char*) "Europe/Podgorica" , 0x0426AF }, + { (char*) "Europe/Prague" , 0x042899 }, + { (char*) "Europe/Riga" , 0x042B78 }, + { (char*) "Europe/Rome" , 0x042E3A }, + { (char*) "Europe/Samara" , 0x0431F9 }, + { (char*) "Europe/San_Marino" , 0x0434FA }, + { (char*) "Europe/Sarajevo" , 0x0438B9 }, + { (char*) "Europe/Saratov" , 0x043AA3 }, + { (char*) "Europe/Simferopol" , 0x043D95 }, + { (char*) "Europe/Skopje" , 0x044108 }, + { (char*) "Europe/Sofia" , 0x0442F2 }, + { (char*) "Europe/Stockholm" , 0x04454E }, + { (char*) "Europe/Tallinn" , 0x04474B }, + { (char*) "Europe/Tirane" , 0x0449FA }, + { (char*) "Europe/Tiraspol" , 0x044C62 }, + { (char*) "Europe/Ulyanovsk" , 0x044F61 }, + { (char*) "Europe/Uzhgorod" , 0x045277 }, + { (char*) "Europe/Vaduz" , 0x0454B1 }, + { (char*) "Europe/Vatican" , 0x04569B }, + { (char*) "Europe/Vienna" , 0x045A5A }, + { (char*) "Europe/Vilnius" , 0x045CF8 }, + { (char*) "Europe/Volgograd" , 0x045FA8 }, + { (char*) "Europe/Warsaw" , 0x0462A5 }, + { (char*) "Europe/Zagreb" , 0x04664C }, + { (char*) "Europe/Zaporozhye" , 0x046836 }, + { (char*) "Europe/Zurich" , 0x046A70 }, + { (char*) "Factory" , 0x046C6D }, + { (char*) "GB" , 0x046CEA }, + { (char*) "GB-Eire" , 0x047335 }, + { (char*) "GMT" , 0x047980 }, + { (char*) "GMT+0" , 0x0479FB }, + { (char*) "GMT-0" , 0x047A76 }, + { (char*) "GMT0" , 0x047AF1 }, + { (char*) "Greenwich" , 0x047B6C }, + { (char*) "Hongkong" , 0x047BE7 }, + { (char*) "HST" , 0x047EFA }, + { (char*) "Iceland" , 0x047F76 }, + { (char*) "Indian/Antananarivo" , 0x048273 }, + { (char*) "Indian/Chagos" , 0x04831F }, + { (char*) "Indian/Christmas" , 0x0483C3 }, + { (char*) "Indian/Cocos" , 0x048454 }, + { (char*) "Indian/Comoro" , 0x0484EC }, + { (char*) "Indian/Kerguelen" , 0x04857B }, + { (char*) "Indian/Mahe" , 0x04860C }, + { (char*) "Indian/Maldives" , 0x04869D }, + { (char*) "Indian/Mauritius" , 0x048741 }, + { (char*) "Indian/Mayotte" , 0x048800 }, + { (char*) "Indian/Reunion" , 0x04888F }, + { (char*) "Iran" , 0x048920 }, + { (char*) "Israel" , 0x048C58 }, + { (char*) "Jamaica" , 0x049096 }, + { (char*) "Japan" , 0x0491F5 }, + { (char*) "Kwajalein" , 0x0492D6 }, + { (char*) "Libya" , 0x0493BD }, + { (char*) "MET" , 0x049578 }, + { (char*) "Mexico/BajaNorte" , 0x0497F1 }, + { (char*) "Mexico/BajaSur" , 0x049BFE }, + { (char*) "Mexico/General" , 0x049D79 }, + { (char*) "MST" , 0x049F21 }, + { (char*) "MST7MDT" , 0x049F9C }, + { (char*) "Navajo" , 0x04A35F }, + { (char*) "NZ" , 0x04A77D }, + { (char*) "NZ-CHAT" , 0x04AB9C }, + { (char*) "Pacific/Apia" , 0x04AED0 }, + { (char*) "Pacific/Auckland" , 0x04B073 }, + { (char*) "Pacific/Bougainville" , 0x04B4AA }, + { (char*) "Pacific/Chatham" , 0x04B58B }, + { (char*) "Pacific/Chuuk" , 0x04B8CE }, + { (char*) "Pacific/Easter" , 0x04B9AC }, + { (char*) "Pacific/Efate" , 0x04BE5B }, + { (char*) "Pacific/Enderbury" , 0x04BFBD }, + { (char*) "Pacific/Fakaofo" , 0x04C075 }, + { (char*) "Pacific/Fiji" , 0x04C11A }, + { (char*) "Pacific/Funafuti" , 0x04C2D2 }, + { (char*) "Pacific/Galapagos" , 0x04C364 }, + { (char*) "Pacific/Gambier" , 0x04C430 }, + { (char*) "Pacific/Guadalcanal" , 0x04C4CF }, + { (char*) "Pacific/Guam" , 0x04C561 }, + { (char*) "Pacific/Honolulu" , 0x04C6CB }, + { (char*) "Pacific/Johnston" , 0x04C7BA }, + { (char*) "Pacific/Kanton" , 0x04C8A3 }, + { (char*) "Pacific/Kiritimati" , 0x04C96A }, + { (char*) "Pacific/Kosrae" , 0x04CA30 }, + { (char*) "Pacific/Kwajalein" , 0x04CB34 }, + { (char*) "Pacific/Majuro" , 0x04CC24 }, + { (char*) "Pacific/Marquesas" , 0x04CD27 }, + { (char*) "Pacific/Midway" , 0x04CDCF }, + { (char*) "Pacific/Nauru" , 0x04CE92 }, + { (char*) "Pacific/Niue" , 0x04CF55 }, + { (char*) "Pacific/Norfolk" , 0x04CFFB }, + { (char*) "Pacific/Noumea" , 0x04D0FE }, + { (char*) "Pacific/Pago_Pago" , 0x04D1D0 }, + { (char*) "Pacific/Palau" , 0x04D26E }, + { (char*) "Pacific/Pitcairn" , 0x04D30E }, + { (char*) "Pacific/Pohnpei" , 0x04D3B3 }, + { (char*) "Pacific/Ponape" , 0x04D4A3 }, + { (char*) "Pacific/Port_Moresby" , 0x04D585 }, + { (char*) "Pacific/Rarotonga" , 0x04D648 }, + { (char*) "Pacific/Saipan" , 0x04D7EA }, + { (char*) "Pacific/Samoa" , 0x04D94B }, + { (char*) "Pacific/Tahiti" , 0x04D9E9 }, + { (char*) "Pacific/Tarawa" , 0x04DA89 }, + { (char*) "Pacific/Tongatapu" , 0x04DB2A }, + { (char*) "Pacific/Truk" , 0x04DC23 }, + { (char*) "Pacific/Wake" , 0x04DCF2 }, + { (char*) "Pacific/Wallis" , 0x04DD8F }, + { (char*) "Pacific/Yap" , 0x04DE21 }, + { (char*) "Poland" , 0x04DEF0 }, + { (char*) "Portugal" , 0x04E297 }, + { (char*) "PRC" , 0x04E851 }, + { (char*) "PST8PDT" , 0x04E9E6 }, + { (char*) "ROC" , 0x04EDA9 }, + { (char*) "ROK" , 0x04EFB4 }, + { (char*) "Singapore" , 0x04F15F }, + { (char*) "Turkey" , 0x04F26B }, + { (char*) "UCT" , 0x04F727 }, + { (char*) "Universal" , 0x04F7A2 }, + { (char*) "US/Alaska" , 0x04F81D }, + { (char*) "US/Aleutian" , 0x04FBFA }, + { (char*) "US/Arizona" , 0x04FFCF }, + { (char*) "US/Central" , 0x0500CB }, + { (char*) "US/East-Indiana" , 0x0507B1 }, + { (char*) "US/Eastern" , 0x0509D0 }, + { (char*) "US/Hawaii" , 0x0510AC }, + { (char*) "US/Indiana-Starke" , 0x051195 }, + { (char*) "US/Michigan" , 0x051599 }, + { (char*) "US/Mountain" , 0x051928 }, + { (char*) "US/Pacific" , 0x051D46 }, + { (char*) "US/Samoa" , 0x052260 }, + { (char*) "UTC" , 0x0522FE }, + { (char*) "W-SU" , 0x052379 }, + { (char*) "WET" , 0x052711 }, + { (char*) "Zulu" , 0x05290B }, }; -const unsigned char timelib_timezone_db_data_builtin[338174] = { +const unsigned char timelib_timezone_db_data_builtin[338310] = { /* Africa/Abidjan */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1268,11 +1268,10 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0xFF, 0xFF, 0xFF, 0xCB, 0x34, 0x3C, 0x10, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x04, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x04, 0xFF, 0xFF, 0xF6, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xF1, 0xF0, -0x00, 0x0E, 0x00, 0x00, 0x04, 0xB0, 0x01, 0x12, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4D, 0x54, 0x00, -0x2D, 0x30, 0x30, 0x34, 0x30, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x0A, 0x58, -0x58, 0x58, 0x2D, 0x30, 0x3A, 0x34, 0x30, 0x3C, 0x2B, 0x30, 0x31, 0x3E, 0x2D, 0x30, 0x3A, 0x32, -0x30, 0x2C, 0x30, 0x2F, 0x30, 0x2C, 0x4A, 0x33, 0x36, 0x35, 0x2F, 0x32, 0x33, 0x3A, 0x34, 0x30, -0x0A, 0x00, 0x96, 0x4C, 0x90, 0x00, 0xFE, 0x70, 0xB8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4D, 0x54, 0x00, +0x2D, 0x30, 0x30, 0x34, 0x30, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x0A, 0x47, +0x4D, 0x54, 0x30, 0x0A, 0x00, 0x96, 0x4C, 0x90, 0x00, 0xFE, 0x70, 0xB8, 0x00, 0x00, 0x00, 0x00, + /* Africa/Gaborone */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x42, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -10619,7 +10618,7 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x33, 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, 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xBD, 0x4A, 0xB0, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x59, 0xCF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0xFA, 0xA6, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x38, 0x9C, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xE5, 0xEB, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xAC, 0xFE, 0x00, 0xFF, @@ -10678,7 +10677,8 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x00, 0x00, 0x00, 0x5A, 0xB5, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xD3, 0x8E, 0x60, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x9D, 0x43, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xB3, 0x62, 0x50, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7E, 0x77, 0x60, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x93, 0x52, 0x60, 0x00, -0x00, 0x00, 0x00, 0x60, 0x5E, 0x59, 0x60, 0x00, 0x00, 0x00, 0x00, 0x61, 0x7B, 0x1D, 0x60, 0x02, +0x00, 0x00, 0x00, 0x60, 0x5E, 0x59, 0x60, 0x00, 0x00, 0x00, 0x00, 0x61, 0x7B, 0x1D, 0x60, 0x00, +0x00, 0x00, 0x00, 0x62, 0x3F, 0x8C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x5C, 0x5E, 0xF0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, @@ -10686,13 +10686,14 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x20, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x01, -0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x09, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x0D, 0x00, 0x00, 0x1C, -0x20, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, -0x49, 0x44, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, -0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x37, 0x32, 0x2C, 0x4D, 0x31, 0x30, -0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x32, 0x35, 0x0A, 0x00, 0xB9, 0x64, 0xF0, 0x01, 0x47, 0x40, 0x0A, -0x00, 0x00, 0x00, 0x0A, 0x47, 0x61, 0x7A, 0x61, 0x20, 0x53, 0x74, 0x72, 0x69, 0x70, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x20, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2A, +0x30, 0x01, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x09, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x0D, 0x00, +0x00, 0x1C, 0x20, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x45, 0x45, +0x54, 0x00, 0x49, 0x44, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, +0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x35, 0x30, 0x2C, 0x4D, +0x31, 0x30, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x35, 0x30, 0x0A, 0x00, 0xB9, 0x64, 0xF0, 0x01, 0x47, +0x40, 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x47, 0x61, 0x7A, 0x61, 0x20, 0x53, 0x74, 0x72, 0x69, 0x70, + /* Asia/Harbin */ 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -10728,7 +10729,7 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x33, 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, 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xBD, 0x4A, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x59, 0xCF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0xFA, 0xA6, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x38, 0x9C, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xE5, 0xEB, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xAC, 0xFE, 0x00, 0xFF, @@ -10788,7 +10789,8 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x00, 0x00, 0x00, 0x5A, 0xB5, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xD3, 0x8E, 0x60, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x9D, 0x43, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xB3, 0x62, 0x50, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7E, 0x77, 0x60, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x93, 0x52, 0x60, 0x00, -0x00, 0x00, 0x00, 0x60, 0x5E, 0x59, 0x60, 0x00, 0x00, 0x00, 0x00, 0x61, 0x7B, 0x1D, 0x60, 0x02, +0x00, 0x00, 0x00, 0x60, 0x5E, 0x59, 0x60, 0x00, 0x00, 0x00, 0x00, 0x61, 0x7B, 0x1D, 0x60, 0x00, +0x00, 0x00, 0x00, 0x62, 0x3F, 0x8C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x5C, 0x5E, 0xF0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, @@ -10796,13 +10798,14 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x20, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x2A, -0x30, 0x01, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x09, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x0D, 0x00, -0x00, 0x1C, 0x20, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x45, 0x45, -0x54, 0x00, 0x49, 0x44, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, -0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x37, 0x32, 0x2C, 0x4D, -0x31, 0x30, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x32, 0x35, 0x0A, 0x00, 0xB9, 0x71, 0xF5, 0x01, 0x48, -0x35, 0x7C, 0x00, 0x00, 0x00, 0x09, 0x57, 0x65, 0x73, 0x74, 0x20, 0x42, 0x61, 0x6E, 0x6B, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x20, 0xE7, 0x00, 0x00, 0x00, +0x00, 0x2A, 0x30, 0x01, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x09, 0x00, 0x00, 0x2A, 0x30, 0x01, +0x0D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, +0x45, 0x45, 0x54, 0x00, 0x49, 0x44, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x0A, 0x45, 0x45, 0x54, +0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x35, 0x30, +0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x35, 0x30, 0x0A, 0x00, 0xB9, 0x71, 0xF5, +0x01, 0x48, 0x35, 0x7C, 0x00, 0x00, 0x00, 0x09, 0x57, 0x65, 0x73, 0x74, 0x20, 0x42, 0x61, 0x6E, +0x6B, /* Asia/Ho_Chi_Minh */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x56, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -19513,16 +19516,16 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x61, 0x6E, 0x6F, 0x76, 0x73, 0x6B, /* Europe/Uzhgorod */ -0x50, 0x48, 0x50, 0x32, 0x01, 0x55, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +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, 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, 0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0xFF, -0xFF, 0xFF, 0xFF, 0x6A, 0xEE, 0xB0, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x09, 0x71, 0x90, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0xFF, +0xFF, 0xFF, 0xFF, 0x56, 0xB6, 0xC7, 0x64, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x19, 0xA7, 0x64, 0xFF, +0xFF, 0xFF, 0xFF, 0xB5, 0xA4, 0x19, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCD, 0x2E, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xE7, 0x4B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xA9, 0x17, 0x90, 0xFF, -0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x92, 0x34, 0x10, 0xFF, -0xFF, 0xFF, 0xFF, 0xD0, 0xA1, 0x9E, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xE5, 0xFD, 0xF0, 0x00, +0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xCD, 0xA8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x15, 0x27, 0xA7, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0xDC, 0x40, 0x00, 0x00, 0x00, 0x00, 0x17, 0x08, 0xDB, 0x50, 0x00, 0x00, 0x00, 0x00, 0x17, 0xFA, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x18, 0xEA, 0x0E, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x19, 0xDB, 0x43, 0x40, 0x00, @@ -19532,23 +19535,23 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x00, 0x00, 0x00, 0x20, 0x6C, 0x55, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x5C, 0x46, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x22, 0x4C, 0x37, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x23, 0x3C, 0x28, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2C, 0x19, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x25, 0x1C, 0x0A, 0xF0, 0x00, -0x00, 0x00, 0x00, 0x26, 0x8D, 0x2E, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x27, 0xF5, 0x42, 0xA0, 0x00, -0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, -0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, -0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, -0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, -0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, -0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x01, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, -0x05, 0x06, 0x05, 0x06, 0x05, 0x00, 0x00, 0x14, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x00, -0x04, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x08, 0x00, 0x00, 0x38, 0x40, 0x01, 0x0D, 0x00, 0x00, 0x2A, -0x30, 0x00, 0x11, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x19, 0x4C, -0x4D, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, -0x4D, 0x53, 0x4B, 0x00, 0x45, 0x45, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x0A, 0x45, 0x45, -0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, -0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0xD3, 0x83, 0x22, 0x01, -0x34, 0xAF, 0x70, 0x00, 0x00, 0x00, 0x0E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x63, 0x61, 0x72, 0x70, -0x61, 0x74, 0x68, 0x69, 0x61, +0x00, 0x00, 0x00, 0x26, 0x0B, 0xFB, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x26, 0x8D, 0x20, 0xE0, 0x00, +0x00, 0x00, 0x00, 0x28, 0xE5, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, +0x00, 0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, +0x00, 0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x01, 0x02, 0x03, 0x05, 0x04, 0x05, 0x04, 0x03, 0x06, +0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, +0x03, 0x06, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x00, 0x00, +0x1C, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x9C, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, +0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x20, +0x01, 0x14, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x4C, 0x4D, +0x54, 0x00, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, +0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, +0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, +0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Europe/Vaduz */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x4C, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -19880,16 +19883,16 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x36, 0xE0, 0x01, 0x2B, 0x05, 0x7A, 0x00, 0x00, 0x00, 0x00, /* Europe/Zaporozhye */ -0x50, 0x48, 0x50, 0x32, 0x01, 0x55, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +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, 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, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0xFF, -0xFF, 0xFF, 0xFF, 0x56, 0xB6, 0xC3, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x19, 0xA3, 0x30, 0xFF, -0xFF, 0xFF, 0xFF, 0xB5, 0xA4, 0x19, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xAA, 0xE7, 0xD0, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0xFF, +0xFF, 0xFF, 0xFF, 0x56, 0xB6, 0xC7, 0x64, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x19, 0xA7, 0x64, 0xFF, +0xFF, 0xFF, 0xFF, 0xB5, 0xA4, 0x19, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCD, 0x2E, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xE7, 0x4B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xA9, 0x17, 0x90, 0xFF, -0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xBD, 0xD6, 0x70, 0x00, +0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xCD, 0xA8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x15, 0x27, 0xA7, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0xDC, 0x40, 0x00, 0x00, 0x00, 0x00, 0x17, 0x08, 0xDB, 0x50, 0x00, 0x00, 0x00, 0x00, 0x17, 0xFA, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x18, 0xEA, 0x0E, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x19, 0xDB, 0x43, 0x40, 0x00, @@ -19899,26 +19902,23 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 0x00, 0x00, 0x00, 0x20, 0x6C, 0x55, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x5C, 0x46, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x22, 0x4C, 0x37, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x23, 0x3C, 0x28, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2C, 0x19, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x25, 0x1C, 0x0A, 0xF0, 0x00, -0x00, 0x00, 0x00, 0x26, 0x0B, 0xFB, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x27, 0x05, 0x27, 0x70, 0x00, -0x00, 0x00, 0x00, 0x27, 0xF5, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, 0xE4, 0xED, 0x50, 0x00, -0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, -0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, -0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, -0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, -0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x01, -0x02, 0x03, 0x05, 0x04, 0x05, 0x04, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, -0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x07, 0x02, 0x07, 0x02, 0x07, -0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x00, 0x00, 0x20, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x20, -0xD0, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0A, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0E, 0x00, -0x00, 0x0E, 0x10, 0x00, 0x12, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x16, 0x00, 0x00, 0x38, 0x40, 0x01, -0x1B, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1F, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x32, 0x32, 0x30, -0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, -0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x0A, 0x45, 0x45, 0x54, 0x2D, -0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, 0x4D, -0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0xD2, 0x51, 0x25, 0x01, 0x48, 0x51, -0x7A, 0x00, 0x00, 0x00, 0x1B, 0x5A, 0x61, 0x70, 0x6F, 0x72, 0x6F, 0x7A, 0x68, 0x79, 0x65, 0x20, -0x61, 0x6E, 0x64, 0x20, 0x65, 0x61, 0x73, 0x74, 0x20, 0x4C, 0x75, 0x67, 0x61, 0x6E, 0x73, 0x6B, - +0x00, 0x00, 0x00, 0x26, 0x0B, 0xFB, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x26, 0x8D, 0x20, 0xE0, 0x00, +0x00, 0x00, 0x00, 0x28, 0xE5, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, +0x00, 0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, +0x00, 0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x01, 0x02, 0x03, 0x05, 0x04, 0x05, 0x04, 0x03, 0x06, +0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, +0x03, 0x06, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x07, 0x02, 0x00, 0x00, +0x1C, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x9C, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, +0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x20, +0x01, 0x14, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x4C, 0x4D, +0x54, 0x00, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, +0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, +0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, +0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Europe/Zurich */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -21667,13 +21667,14 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 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, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x37, 0x5B, 0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x75, 0x8A, 0xB0, 0xFF, -0xFF, 0xFF, 0xFF, 0xE6, 0xED, 0x75, 0x20, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0x59, 0xB8, 0x00, 0x00, -0xFF, 0xFF, 0x65, 0x50, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, -0x2D, 0x31, 0x31, 0x00, 0x2D, 0x31, 0x30, 0x00, 0x0A, 0x3C, 0x2D, 0x31, 0x31, 0x3E, 0x31, 0x31, -0x0A, 0x00, 0xB4, 0x62, 0x62, 0x00, 0x04, 0x04, 0xA5, 0x00, 0x00, 0x00, 0x0E, 0x4D, 0x69, 0x64, -0x77, 0x61, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, +0xFF, 0xFF, 0xFF, 0xE6, 0xED, 0x75, 0x20, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0x59, 0xB8, 0x00, 0x00, +0xFF, 0xFF, 0x65, 0x50, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x08, 0xFF, 0xFF, 0x65, 0x50, +0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x31, 0x31, 0x00, 0x2D, 0x31, 0x30, 0x00, 0x53, 0x53, +0x54, 0x00, 0x0A, 0x53, 0x53, 0x54, 0x31, 0x31, 0x0A, 0x00, 0xB4, 0x62, 0x62, 0x00, 0x04, 0x04, +0xA5, 0x00, 0x00, 0x00, 0x0E, 0x4D, 0x69, 0x64, 0x77, 0x61, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, +0x6E, 0x64, 0x73, /* Pacific/Nauru */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x4E, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -21861,14 +21862,24 @@ const unsigned char timelib_timezone_db_data_builtin[338174] = { 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, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xE1, 0xC4, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x36, 0x2C, 0x5C, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0x86, 0x37, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x43, 0x5E, 0x60, 0x01, -0x02, 0x03, 0x04, 0xFF, 0xFF, 0x37, 0x24, 0x00, 0x00, 0x00, 0x00, 0x88, 0xA4, 0x00, 0x00, 0x00, -0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x08, 0x00, 0x00, 0x8C, 0xA0, 0x00, -0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x2B, 0x31, 0x30, 0x00, 0x43, 0x68, 0x53, -0x54, 0x00, 0x0A, 0x43, 0x68, 0x53, 0x54, 0x2D, 0x31, 0x30, 0x0A, 0x00, 0xA0, 0x85, 0xC0, 0x01, -0xF1, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xD0, 0x11, 0x88, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x37, 0xBE, 0x00, 0xFF, +0xFF, 0xFF, 0xFF, 0xEF, 0x36, 0xF8, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x9B, 0x00, 0x00, 0xFF, +0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0x27, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x1E, 0x00, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0x58, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x2C, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x46, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0x0E, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x26, 0x57, 0x70, 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x97, 0x00, 0x00, +0x00, 0x00, 0x00, 0x07, 0xCC, 0xD1, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x08, 0x91, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0C, 0x7C, 0x87, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xBF, 0x94, 0x80, 0x00, +0x00, 0x00, 0x00, 0x0E, 0x65, 0xA3, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x43, 0x5E, 0x60, 0x01, +0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x05, 0xFF, 0xFF, 0x37, 0x24, 0x00, 0x00, 0x00, 0x00, 0x88, 0xA4, 0x00, 0x00, 0x00, +0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x08, 0x00, 0x00, 0x8C, 0xA0, 0x00, +0x0C, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x47, +0x44, 0x54, 0x00, 0x47, 0x53, 0x54, 0x00, 0x43, 0x68, 0x53, 0x54, 0x00, 0x0A, 0x43, 0x68, 0x53, +0x54, 0x2D, 0x31, 0x30, 0x0A, 0x00, 0xA0, 0x85, 0xC0, 0x01, 0xF1, 0x0E, 0x18, 0x00, 0x00, 0x00, +0x00, /* Pacific/Samoa */ 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -23260,583 +23271,583 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[596] = { { (char*) "Africa/Douala" , 0x002BE4 }, { (char*) "Africa/El_Aaiun" , 0x002C85 }, { (char*) "Africa/Freetown" , 0x003588 }, - { (char*) "Africa/Gaborone" , 0x00378F }, - { (char*) "Africa/Harare" , 0x003886 }, - { (char*) "Africa/Johannesburg" , 0x003927 }, - { (char*) "Africa/Juba" , 0x003A29 }, - { (char*) "Africa/Kampala" , 0x003CDC }, - { (char*) "Africa/Khartoum" , 0x003DE3 }, - { (char*) "Africa/Kigali" , 0x004096 }, - { (char*) "Africa/Kinshasa" , 0x004137 }, - { (char*) "Africa/Lagos" , 0x0041F1 }, - { (char*) "Africa/Libreville" , 0x0042E8 }, - { (char*) "Africa/Lome" , 0x004389 }, - { (char*) "Africa/Luanda" , 0x004429 }, - { (char*) "Africa/Lubumbashi" , 0x0044F0 }, - { (char*) "Africa/Lusaka" , 0x0045CC }, - { (char*) "Africa/Malabo" , 0x00466D }, - { (char*) "Africa/Maputo" , 0x004730 }, - { (char*) "Africa/Maseru" , 0x0047D1 }, - { (char*) "Africa/Mbabane" , 0x00489D }, - { (char*) "Africa/Mogadishu" , 0x004941 }, - { (char*) "Africa/Monrovia" , 0x004A22 }, - { (char*) "Africa/Nairobi" , 0x004AFE }, - { (char*) "Africa/Ndjamena" , 0x004C13 }, - { (char*) "Africa/Niamey" , 0x004CE6 }, - { (char*) "Africa/Nouakchott" , 0x004DCB }, - { (char*) "Africa/Ouagadougou" , 0x004EA7 }, - { (char*) "Africa/Porto-Novo" , 0x004F47 }, - { (char*) "Africa/Sao_Tome" , 0x00500A }, - { (char*) "Africa/Timbuktu" , 0x005114 }, - { (char*) "Africa/Tripoli" , 0x0051F0 }, - { (char*) "Africa/Tunis" , 0x00546D }, - { (char*) "Africa/Windhoek" , 0x00572A }, - { (char*) "America/Adak" , 0x005AF1 }, - { (char*) "America/Anchorage" , 0x006441 }, - { (char*) "America/Anguilla" , 0x006DA3 }, - { (char*) "America/Antigua" , 0x006E43 }, - { (char*) "America/Araguaina" , 0x006F05 }, - { (char*) "America/Argentina/Buenos_Aires" , 0x00728E }, - { (char*) "America/Argentina/Catamarca" , 0x0076E3 }, - { (char*) "America/Argentina/ComodRivadavia" , 0x007B3E }, - { (char*) "America/Argentina/Cordoba" , 0x007F7E }, - { (char*) "America/Argentina/Jujuy" , 0x0083F4 }, - { (char*) "America/Argentina/La_Rioja" , 0x008822 }, - { (char*) "America/Argentina/Mendoza" , 0x008C7D }, - { (char*) "America/Argentina/Rio_Gallegos" , 0x0090C9 }, - { (char*) "America/Argentina/Salta" , 0x009518 }, - { (char*) "America/Argentina/San_Juan" , 0x009952 }, - { (char*) "America/Argentina/San_Luis" , 0x009DAD }, - { (char*) "America/Argentina/Tucuman" , 0x00A214 }, - { (char*) "America/Argentina/Ushuaia" , 0x00A67C }, - { (char*) "America/Aruba" , 0x00AAD1 }, - { (char*) "America/Asuncion" , 0x00AB97 }, - { (char*) "America/Atikokan" , 0x00B39F }, - { (char*) "America/Atka" , 0x00B51C }, - { (char*) "America/Bahia" , 0x00BE5C }, - { (char*) "America/Bahia_Banderas" , 0x00C26D }, - { (char*) "America/Barbados" , 0x00C8A3 }, - { (char*) "America/Belem" , 0x00CA63 }, - { (char*) "America/Belize" , 0x00CCC1 }, - { (char*) "America/Blanc-Sablon" , 0x00D31B }, - { (char*) "America/Boa_Vista" , 0x00D46D }, - { (char*) "America/Bogota" , 0x00D6F8 }, - { (char*) "America/Boise" , 0x00D7FA }, - { (char*) "America/Buenos_Aires" , 0x00E180 }, - { (char*) "America/Cambridge_Bay" , 0x00E5C0 }, - { (char*) "America/Campo_Grande" , 0x00EE04 }, - { (char*) "America/Cancun" , 0x00F3C6 }, - { (char*) "America/Caracas" , 0x00F704 }, - { (char*) "America/Catamarca" , 0x00F818 }, - { (char*) "America/Cayenne" , 0x00FC58 }, - { (char*) "America/Cayman" , 0x00FD2A }, - { (char*) "America/Chicago" , 0x00FDEC }, - { (char*) "America/Chihuahua" , 0x010C04 }, - { (char*) "America/Coral_Harbour" , 0x011202 }, - { (char*) "America/Cordoba" , 0x01135E }, - { (char*) "America/Costa_Rica" , 0x01179E }, - { (char*) "America/Creston" , 0x0118E6 }, - { (char*) "America/Cuiaba" , 0x0119D4 }, - { (char*) "America/Curacao" , 0x011F73 }, - { (char*) "America/Danmarkshavn" , 0x012039 }, - { (char*) "America/Dawson" , 0x012319 }, - { (char*) "America/Dawson_Creek" , 0x012985 }, - { (char*) "America/Denver" , 0x012DCB }, - { (char*) "America/Detroit" , 0x013778 }, - { (char*) "America/Dominica" , 0x014053 }, - { (char*) "America/Edmonton" , 0x0140F3 }, - { (char*) "America/Eirunepe" , 0x014A38 }, - { (char*) "America/El_Salvador" , 0x014CE3 }, - { (char*) "America/Ensenada" , 0x014DCF }, - { (char*) "America/Fort_Nelson" , 0x015701 }, - { (char*) "America/Fort_Wayne" , 0x015FE1 }, - { (char*) "America/Fortaleza" , 0x01666F }, - { (char*) "America/Glace_Bay" , 0x01696D }, - { (char*) "America/Godthab" , 0x017224 }, - { (char*) "America/Goose_Bay" , 0x017986 }, - { (char*) "America/Grand_Turk" , 0x01863C }, - { (char*) "America/Grenada" , 0x018D72 }, - { (char*) "America/Guadeloupe" , 0x018E12 }, - { (char*) "America/Guatemala" , 0x018EB2 }, - { (char*) "America/Guayaquil" , 0x018FD6 }, - { (char*) "America/Guyana" , 0x0190EA }, - { (char*) "America/Halifax" , 0x0191FC }, - { (char*) "America/Havana" , 0x019F86 }, - { (char*) "America/Hermosillo" , 0x01A902 }, - { (char*) "America/Indiana/Indianapolis" , 0x01AACD }, - { (char*) "America/Indiana/Knox" , 0x01B174 }, - { (char*) "America/Indiana/Marengo" , 0x01BB11 }, - { (char*) "America/Indiana/Petersburg" , 0x01C1EE }, - { (char*) "America/Indiana/Tell_City" , 0x01C97D }, - { (char*) "America/Indiana/Vevay" , 0x01D031 }, - { (char*) "America/Indiana/Vincennes" , 0x01D5DD }, - { (char*) "America/Indiana/Winamac" , 0x01DCA3 }, - { (char*) "America/Indianapolis" , 0x01E3B7 }, - { (char*) "America/Inuvik" , 0x01EA45 }, - { (char*) "America/Iqaluit" , 0x01F1CB }, - { (char*) "America/Jamaica" , 0x01F9E5 }, - { (char*) "America/Jujuy" , 0x01FBD3 }, - { (char*) "America/Juneau" , 0x01FFF7 }, - { (char*) "America/Kentucky/Louisville" , 0x020948 }, - { (char*) "America/Kentucky/Monticello" , 0x021446 }, - { (char*) "America/Knox_IN" , 0x021D96 }, - { (char*) "America/Kralendijk" , 0x02271E }, - { (char*) "America/La_Paz" , 0x0227E4 }, - { (char*) "America/Lima" , 0x0228D8 }, - { (char*) "America/Los_Angeles" , 0x022A7A }, - { (char*) "America/Louisville" , 0x0235A1 }, - { (char*) "America/Lower_Princes" , 0x024081 }, - { (char*) "America/Maceio" , 0x024147 }, - { (char*) "America/Managua" , 0x02444B }, - { (char*) "America/Manaus" , 0x024605 }, - { (char*) "America/Marigot" , 0x02487C }, - { (char*) "America/Martinique" , 0x02491C }, - { (char*) "America/Matamoros" , 0x024A10 }, - { (char*) "America/Mazatlan" , 0x024FC8 }, - { (char*) "America/Mendoza" , 0x0255FF }, - { (char*) "America/Menominee" , 0x025A3F }, - { (char*) "America/Merida" , 0x02634C }, - { (char*) "America/Metlakatla" , 0x026906 }, - { (char*) "America/Mexico_City" , 0x026EB8 }, - { (char*) "America/Miquelon" , 0x027500 }, - { (char*) "America/Moncton" , 0x027B8E }, - { (char*) "America/Monterrey" , 0x028804 }, - { (char*) "America/Montevideo" , 0x028DC3 }, - { (char*) "America/Montreal" , 0x0293B5 }, - { (char*) "America/Montserrat" , 0x02A167 }, - { (char*) "America/Nassau" , 0x02A207 }, - { (char*) "America/New_York" , 0x02AB67 }, - { (char*) "America/Nipigon" , 0x02B967 }, - { (char*) "America/Nome" , 0x02C1DE }, - { (char*) "America/Noronha" , 0x02CB36 }, - { (char*) "America/North_Dakota/Beulah" , 0x02CE1E }, - { (char*) "America/North_Dakota/Center" , 0x02D78B }, - { (char*) "America/North_Dakota/New_Salem" , 0x02E0F8 }, - { (char*) "America/Nuuk" , 0x02EA6B }, - { (char*) "America/Ojinaga" , 0x02F1E3 }, - { (char*) "America/Panama" , 0x02F7E3 }, - { (char*) "America/Pangnirtung" , 0x02F8A5 }, - { (char*) "America/Paramaribo" , 0x0300F9 }, - { (char*) "America/Phoenix" , 0x03020B }, - { (char*) "America/Port-au-Prince" , 0x03037C }, - { (char*) "America/Port_of_Spain" , 0x030922 }, - { (char*) "America/Porto_Acre" , 0x0309C2 }, - { (char*) "America/Porto_Velho" , 0x030C42 }, - { (char*) "America/Puerto_Rico" , 0x030E96 }, - { (char*) "America/Punta_Arenas" , 0x030F98 }, - { (char*) "America/Rainy_River" , 0x031734 }, - { (char*) "America/Rankin_Inlet" , 0x031FAC }, - { (char*) "America/Recife" , 0x032732 }, - { (char*) "America/Regina" , 0x032A14 }, - { (char*) "America/Resolute" , 0x032E09 }, - { (char*) "America/Rio_Branco" , 0x033590 }, - { (char*) "America/Rosario" , 0x033814 }, - { (char*) "America/Santa_Isabel" , 0x033C54 }, - { (char*) "America/Santarem" , 0x034586 }, - { (char*) "America/Santiago" , 0x0347F7 }, - { (char*) "America/Santo_Domingo" , 0x0351F6 }, - { (char*) "America/Sao_Paulo" , 0x0353CC }, - { (char*) "America/Scoresbysund" , 0x0359B2 }, - { (char*) "America/Shiprock" , 0x036157 }, - { (char*) "America/Sitka" , 0x036AEF }, - { (char*) "America/St_Barthelemy" , 0x037427 }, - { (char*) "America/St_Johns" , 0x0374C7 }, - { (char*) "America/St_Kitts" , 0x03833C }, - { (char*) "America/St_Lucia" , 0x0383DC }, - { (char*) "America/St_Thomas" , 0x03849E }, - { (char*) "America/St_Vincent" , 0x03853E }, - { (char*) "America/Swift_Current" , 0x038600 }, - { (char*) "America/Tegucigalpa" , 0x03884E }, - { (char*) "America/Thule" , 0x038956 }, - { (char*) "America/Thunder_Bay" , 0x038F4E }, - { (char*) "America/Tijuana" , 0x03980E }, - { (char*) "America/Toronto" , 0x03A161 }, - { (char*) "America/Tortola" , 0x03AF30 }, - { (char*) "America/Vancouver" , 0x03AFD0 }, - { (char*) "America/Virgin" , 0x03BB41 }, - { (char*) "America/Whitehorse" , 0x03BBE1 }, - { (char*) "America/Winnipeg" , 0x03C24D }, - { (char*) "America/Yakutat" , 0x03CDAA }, - { (char*) "America/Yellowknife" , 0x03D6C7 }, - { (char*) "Antarctica/Casey" , 0x03DE98 }, - { (char*) "Antarctica/Davis" , 0x03E029 }, - { (char*) "Antarctica/DumontDUrville" , 0x03E163 }, - { (char*) "Antarctica/Macquarie" , 0x03E241 }, - { (char*) "Antarctica/Mawson" , 0x03EB31 }, - { (char*) "Antarctica/McMurdo" , 0x03EC0A }, - { (char*) "Antarctica/Palmer" , 0x03F405 }, - { (char*) "Antarctica/Rothera" , 0x03F9A1 }, - { (char*) "Antarctica/South_Pole" , 0x03FA58 }, - { (char*) "Antarctica/Syowa" , 0x04022D }, - { (char*) "Antarctica/Troll" , 0x0402E3 }, - { (char*) "Antarctica/Vostok" , 0x04077E }, - { (char*) "Arctic/Longyearbyen" , 0x040835 }, - { (char*) "Asia/Aden" , 0x0410F5 }, - { (char*) "Asia/Almaty" , 0x0411A6 }, - { (char*) "Asia/Amman" , 0x0415AE }, - { (char*) "Asia/Anadyr" , 0x041CF7 }, - { (char*) "Asia/Aqtau" , 0x0421BA }, - { (char*) "Asia/Aqtobe" , 0x0425B2 }, - { (char*) "Asia/Ashgabat" , 0x0429BE }, - { (char*) "Asia/Ashkhabad" , 0x042C35 }, - { (char*) "Asia/Atyrau" , 0x042EAC }, - { (char*) "Asia/Baghdad" , 0x0432AC }, - { (char*) "Asia/Bahrain" , 0x04368F }, - { (char*) "Asia/Baku" , 0x043788 }, - { (char*) "Asia/Bangkok" , 0x043C5F }, - { (char*) "Asia/Barnaul" , 0x043D32 }, - { (char*) "Asia/Beirut" , 0x044211 }, - { (char*) "Asia/Bishkek" , 0x044A87 }, - { (char*) "Asia/Brunei" , 0x044E6A }, - { (char*) "Asia/Calcutta" , 0x044F41 }, - { (char*) "Asia/Chita" , 0x04506A }, - { (char*) "Asia/Choibalsan" , 0x04554F }, - { (char*) "Asia/Chongqing" , 0x045922 }, - { (char*) "Asia/Chungking" , 0x045B5F }, - { (char*) "Asia/Colombo" , 0x045D9C }, - { (char*) "Asia/Dacca" , 0x045F1C }, - { (char*) "Asia/Damascus" , 0x046079 }, - { (char*) "Asia/Dhaka" , 0x04697B }, - { (char*) "Asia/Dili" , 0x046AD8 }, - { (char*) "Asia/Dubai" , 0x046BC7 }, - { (char*) "Asia/Dushanbe" , 0x046C78 }, - { (char*) "Asia/Famagusta" , 0x046ED3 }, - { (char*) "Asia/Gaza" , 0x0476DA }, - { (char*) "Asia/Harbin" , 0x048066 }, - { (char*) "Asia/Hebron" , 0x0482A3 }, - { (char*) "Asia/Ho_Chi_Minh" , 0x048C4A }, - { (char*) "Asia/Hong_Kong" , 0x048DB5 }, - { (char*) "Asia/Hovd" , 0x049292 }, - { (char*) "Asia/Irkutsk" , 0x049644 }, - { (char*) "Asia/Istanbul" , 0x049B45 }, - { (char*) "Asia/Jakarta" , 0x04A2EC }, - { (char*) "Asia/Jayapura" , 0x04A484 }, - { (char*) "Asia/Jerusalem" , 0x04A5A3 }, - { (char*) "Asia/Kabul" , 0x04AF03 }, - { (char*) "Asia/Kamchatka" , 0x04AFDF }, - { (char*) "Asia/Karachi" , 0x04B48B }, - { (char*) "Asia/Kashgar" , 0x04B612 }, - { (char*) "Asia/Kathmandu" , 0x04B6C3 }, - { (char*) "Asia/Katmandu" , 0x04B7A3 }, - { (char*) "Asia/Khandyga" , 0x04B883 }, - { (char*) "Asia/Kolkata" , 0x04BDA4 }, - { (char*) "Asia/Krasnoyarsk" , 0x04BECD }, - { (char*) "Asia/Kuala_Lumpur" , 0x04C3A9 }, - { (char*) "Asia/Kuching" , 0x04C548 }, - { (char*) "Asia/Kuwait" , 0x04C745 }, - { (char*) "Asia/Macao" , 0x04C7F6 }, - { (char*) "Asia/Macau" , 0x04CCCD }, - { (char*) "Asia/Magadan" , 0x04D1A4 }, - { (char*) "Asia/Makassar" , 0x04D686 }, - { (char*) "Asia/Manila" , 0x04D7D9 }, - { (char*) "Asia/Muscat" , 0x04D92D }, - { (char*) "Asia/Nicosia" , 0x04D9DE }, - { (char*) "Asia/Novokuznetsk" , 0x04E1CF }, - { (char*) "Asia/Novosibirsk" , 0x04E679 }, - { (char*) "Asia/Omsk" , 0x04EB5E }, - { (char*) "Asia/Oral" , 0x04F02E }, - { (char*) "Asia/Phnom_Penh" , 0x04F436 }, - { (char*) "Asia/Pontianak" , 0x04F569 }, - { (char*) "Asia/Pyongyang" , 0x04F6EC }, - { (char*) "Asia/Qatar" , 0x04F7E5 }, - { (char*) "Asia/Qostanay" , 0x04F8B8 }, - { (char*) "Asia/Qyzylorda" , 0x04FCD1 }, - { (char*) "Asia/Rangoon" , 0x0500FB }, - { (char*) "Asia/Riyadh" , 0x050213 }, - { (char*) "Asia/Saigon" , 0x0502C4 }, - { (char*) "Asia/Sakhalin" , 0x05042F }, - { (char*) "Asia/Samarkand" , 0x050905 }, - { (char*) "Asia/Seoul" , 0x050B63 }, - { (char*) "Asia/Shanghai" , 0x050DD8 }, - { (char*) "Asia/Singapore" , 0x051021 }, - { (char*) "Asia/Srednekolymsk" , 0x0511AC }, - { (char*) "Asia/Taipei" , 0x051692 }, - { (char*) "Asia/Tashkent" , 0x051997 }, - { (char*) "Asia/Tbilisi" , 0x051C03 }, - { (char*) "Asia/Tehran" , 0x05201A }, - { (char*) "Asia/Tel_Aviv" , 0x052514 }, - { (char*) "Asia/Thimbu" , 0x052E74 }, - { (char*) "Asia/Thimphu" , 0x052F4B }, - { (char*) "Asia/Tokyo" , 0x053022 }, - { (char*) "Asia/Tomsk" , 0x053163 }, - { (char*) "Asia/Ujung_Pandang" , 0x053642 }, - { (char*) "Asia/Ulaanbaatar" , 0x05374C }, - { (char*) "Asia/Ulan_Bator" , 0x053AE8 }, - { (char*) "Asia/Urumqi" , 0x053E6F }, - { (char*) "Asia/Ust-Nera" , 0x053F2D }, - { (char*) "Asia/Vientiane" , 0x054431 }, - { (char*) "Asia/Vladivostok" , 0x054580 }, - { (char*) "Asia/Yakutsk" , 0x054A57 }, - { (char*) "Asia/Yangon" , 0x054F2D }, - { (char*) "Asia/Yekaterinburg" , 0x055045 }, - { (char*) "Asia/Yerevan" , 0x05553A }, - { (char*) "Atlantic/Azores" , 0x0559C5 }, - { (char*) "Atlantic/Bermuda" , 0x05678F }, - { (char*) "Atlantic/Canary" , 0x0570F7 }, - { (char*) "Atlantic/Cape_Verde" , 0x05787A }, - { (char*) "Atlantic/Faeroe" , 0x057994 }, - { (char*) "Atlantic/Faroe" , 0x0580B7 }, - { (char*) "Atlantic/Jan_Mayen" , 0x0587DA }, - { (char*) "Atlantic/Madeira" , 0x05909A }, - { (char*) "Atlantic/Reykjavik" , 0x059E64 }, - { (char*) "Atlantic/South_Georgia" , 0x05A2FA }, - { (char*) "Atlantic/St_Helena" , 0x05A3AA }, - { (char*) "Atlantic/Stanley" , 0x05A46C }, - { (char*) "Australia/ACT" , 0x05A936 }, - { (char*) "Australia/Adelaide" , 0x05B1D0 }, - { (char*) "Australia/Brisbane" , 0x05BA8B }, - { (char*) "Australia/Broken_Hill" , 0x05BC51 }, - { (char*) "Australia/Canberra" , 0x05C52E }, - { (char*) "Australia/Currie" , 0x05CDC8 }, - { (char*) "Australia/Darwin" , 0x05D70A }, - { (char*) "Australia/Eucla" , 0x05D86D }, - { (char*) "Australia/Hobart" , 0x05DA68 }, - { (char*) "Australia/LHI" , 0x05E3B2 }, - { (char*) "Australia/Lindeman" , 0x05EB02 }, - { (char*) "Australia/Lord_Howe" , 0x05ED08 }, - { (char*) "Australia/Melbourne" , 0x05F468 }, - { (char*) "Australia/North" , 0x05FD0A }, - { (char*) "Australia/NSW" , 0x05FE5B }, - { (char*) "Australia/Perth" , 0x0606F5 }, - { (char*) "Australia/Queensland" , 0x0608DD }, - { (char*) "Australia/South" , 0x060A8C }, - { (char*) "Australia/Sydney" , 0x061338 }, - { (char*) "Australia/Tasmania" , 0x061BEE }, - { (char*) "Australia/Victoria" , 0x062530 }, - { (char*) "Australia/West" , 0x062DCA }, - { (char*) "Australia/Yancowinna" , 0x062F94 }, - { (char*) "Brazil/Acre" , 0x063855 }, - { (char*) "Brazil/DeNoronha" , 0x063AD5 }, - { (char*) "Brazil/East" , 0x063DAD }, - { (char*) "Brazil/West" , 0x06435D }, - { (char*) "Canada/Atlantic" , 0x0645C5 }, - { (char*) "Canada/Central" , 0x065331 }, - { (char*) "Canada/Eastern" , 0x065E71 }, - { (char*) "Canada/Mountain" , 0x066C23 }, - { (char*) "Canada/Newfoundland" , 0x06754B }, - { (char*) "Canada/Pacific" , 0x06839E }, - { (char*) "Canada/Saskatchewan" , 0x068EF6 }, - { (char*) "Canada/Yukon" , 0x0692D6 }, - { (char*) "CET" , 0x069930 }, - { (char*) "Chile/Continental" , 0x06A16A }, - { (char*) "Chile/EasterIsland" , 0x06AB57 }, - { (char*) "CST6CDT" , 0x06B41C }, - { (char*) "Cuba" , 0x06BD2E }, - { (char*) "EET" , 0x06C6AA }, - { (char*) "Egypt" , 0x06CE2A }, - { (char*) "Eire" , 0x06D5D9 }, - { (char*) "EST" , 0x06E389 }, - { (char*) "EST5EDT" , 0x06E407 }, - { (char*) "Etc/GMT" , 0x06ED19 }, - { (char*) "Etc/GMT+0" , 0x06ED97 }, - { (char*) "Etc/GMT+1" , 0x06EE15 }, - { (char*) "Etc/GMT+10" , 0x06EE95 }, - { (char*) "Etc/GMT+11" , 0x06EF16 }, - { (char*) "Etc/GMT+12" , 0x06EF97 }, - { (char*) "Etc/GMT+2" , 0x06F018 }, - { (char*) "Etc/GMT+3" , 0x06F098 }, - { (char*) "Etc/GMT+4" , 0x06F118 }, - { (char*) "Etc/GMT+5" , 0x06F198 }, - { (char*) "Etc/GMT+6" , 0x06F218 }, - { (char*) "Etc/GMT+7" , 0x06F298 }, - { (char*) "Etc/GMT+8" , 0x06F318 }, - { (char*) "Etc/GMT+9" , 0x06F398 }, - { (char*) "Etc/GMT-0" , 0x06F418 }, - { (char*) "Etc/GMT-1" , 0x06F496 }, - { (char*) "Etc/GMT-10" , 0x06F517 }, - { (char*) "Etc/GMT-11" , 0x06F599 }, - { (char*) "Etc/GMT-12" , 0x06F61B }, - { (char*) "Etc/GMT-13" , 0x06F69D }, - { (char*) "Etc/GMT-14" , 0x06F71F }, - { (char*) "Etc/GMT-2" , 0x06F7A1 }, - { (char*) "Etc/GMT-3" , 0x06F822 }, - { (char*) "Etc/GMT-4" , 0x06F8A3 }, - { (char*) "Etc/GMT-5" , 0x06F924 }, - { (char*) "Etc/GMT-6" , 0x06F9A5 }, - { (char*) "Etc/GMT-7" , 0x06FA26 }, - { (char*) "Etc/GMT-8" , 0x06FAA7 }, - { (char*) "Etc/GMT-9" , 0x06FB28 }, - { (char*) "Etc/GMT0" , 0x06FBA9 }, - { (char*) "Etc/Greenwich" , 0x06FC27 }, - { (char*) "Etc/UCT" , 0x06FCA5 }, - { (char*) "Etc/Universal" , 0x06FD23 }, - { (char*) "Etc/UTC" , 0x06FDA1 }, - { (char*) "Etc/Zulu" , 0x06FE1F }, - { (char*) "Europe/Amsterdam" , 0x06FE9D }, - { (char*) "Europe/Andorra" , 0x070A07 }, - { (char*) "Europe/Astrakhan" , 0x0710E1 }, - { (char*) "Europe/Athens" , 0x07158C }, - { (char*) "Europe/Belfast" , 0x071E6E }, - { (char*) "Europe/Belgrade" , 0x072CCA }, - { (char*) "Europe/Berlin" , 0x073456 }, - { (char*) "Europe/Bratislava" , 0x073D70 }, - { (char*) "Europe/Brussels" , 0x074679 }, - { (char*) "Europe/Bucharest" , 0x0751FA }, - { (char*) "Europe/Budapest" , 0x075A8E }, - { (char*) "Europe/Busingen" , 0x0763DA }, - { (char*) "Europe/Chisinau" , 0x076B63 }, - { (char*) "Europe/Copenhagen" , 0x0774C5 }, - { (char*) "Europe/Dublin" , 0x077D2A }, - { (char*) "Europe/Gibraltar" , 0x078ADA }, - { (char*) "Europe/Guernsey" , 0x0796E2 }, - { (char*) "Europe/Helsinki" , 0x07A582 }, - { (char*) "Europe/Isle_of_Man" , 0x07ACFA }, - { (char*) "Europe/Istanbul" , 0x07BB46 }, - { (char*) "Europe/Jersey" , 0x07C2ED }, - { (char*) "Europe/Kaliningrad" , 0x07D18D }, - { (char*) "Europe/Kiev" , 0x07D782 }, - { (char*) "Europe/Kirov" , 0x07DFD6 }, - { (char*) "Europe/Kyiv" , 0x07E471 }, - { (char*) "Europe/Lisbon" , 0x07ECD9 }, - { (char*) "Europe/Ljubljana" , 0x07FAA1 }, - { (char*) "Europe/London" , 0x08022D }, - { (char*) "Europe/Luxembourg" , 0x081089 }, - { (char*) "Europe/Madrid" , 0x081C17 }, - { (char*) "Europe/Malta" , 0x082669 }, - { (char*) "Europe/Mariehamn" , 0x0830B1 }, - { (char*) "Europe/Minsk" , 0x083829 }, - { (char*) "Europe/Monaco" , 0x083D5E }, - { (char*) "Europe/Moscow" , 0x0848EA }, - { (char*) "Europe/Nicosia" , 0x084F09 }, - { (char*) "Europe/Oslo" , 0x0856E7 }, - { (char*) "Europe/Paris" , 0x085FA7 }, - { (char*) "Europe/Podgorica" , 0x086B45 }, - { (char*) "Europe/Prague" , 0x0872D1 }, - { (char*) "Europe/Riga" , 0x087BDA }, - { (char*) "Europe/Rome" , 0x08847C }, - { (char*) "Europe/Samara" , 0x088ED9 }, - { (char*) "Europe/San_Marino" , 0x0893BD }, - { (char*) "Europe/Sarajevo" , 0x089E1A }, - { (char*) "Europe/Saratov" , 0x08A5A6 }, - { (char*) "Europe/Simferopol" , 0x08AA61 }, - { (char*) "Europe/Skopje" , 0x08B030 }, - { (char*) "Europe/Sofia" , 0x08B7BC }, - { (char*) "Europe/Stockholm" , 0x08BFE5 }, - { (char*) "Europe/Tallinn" , 0x08C766 }, - { (char*) "Europe/Tirane" , 0x08CFD6 }, - { (char*) "Europe/Tiraspol" , 0x08D806 }, - { (char*) "Europe/Ulyanovsk" , 0x08E168 }, - { (char*) "Europe/Uzhgorod" , 0x08E679 }, - { (char*) "Europe/Vaduz" , 0x08EEA5 }, - { (char*) "Europe/Vatican" , 0x08F611 }, - { (char*) "Europe/Vienna" , 0x09006E }, - { (char*) "Europe/Vilnius" , 0x090912 }, - { (char*) "Europe/Volgograd" , 0x091190 }, - { (char*) "Europe/Warsaw" , 0x09163B }, - { (char*) "Europe/Zagreb" , 0x0920A5 }, - { (char*) "Europe/Zaporozhye" , 0x092831 }, - { (char*) "Europe/Zurich" , 0x0930B2 }, - { (char*) "Factory" , 0x093833 }, - { (char*) "GB" , 0x0938B3 }, - { (char*) "GB-Eire" , 0x09470F }, - { (char*) "GMT" , 0x09556B }, - { (char*) "GMT+0" , 0x0955E9 }, - { (char*) "GMT-0" , 0x095667 }, - { (char*) "GMT0" , 0x0956E5 }, - { (char*) "Greenwich" , 0x095763 }, - { (char*) "Hongkong" , 0x0957E1 }, - { (char*) "HST" , 0x095CBE }, - { (char*) "Iceland" , 0x095D3D }, - { (char*) "Indian/Antananarivo" , 0x0961D3 }, - { (char*) "Indian/Chagos" , 0x0962BA }, - { (char*) "Indian/Christmas" , 0x09638D }, - { (char*) "Indian/Cocos" , 0x09643E }, - { (char*) "Indian/Comoro" , 0x0964F8 }, - { (char*) "Indian/Kerguelen" , 0x096599 }, - { (char*) "Indian/Mahe" , 0x09664A }, - { (char*) "Indian/Maldives" , 0x0966FB }, - { (char*) "Indian/Mauritius" , 0x0967CE }, - { (char*) "Indian/Mayotte" , 0x0968CB }, - { (char*) "Indian/Reunion" , 0x09696C }, - { (char*) "Iran" , 0x096A1D }, - { (char*) "Israel" , 0x096F17 }, - { (char*) "Jamaica" , 0x097877 }, - { (char*) "Japan" , 0x097A65 }, - { (char*) "Kwajalein" , 0x097BA6 }, - { (char*) "Libya" , 0x097CEE }, - { (char*) "MET" , 0x097F6B }, - { (char*) "Mexico/BajaNorte" , 0x0987A5 }, - { (char*) "Mexico/BajaSur" , 0x0990D7 }, - { (char*) "Mexico/General" , 0x0996D9 }, - { (char*) "MST" , 0x099D15 }, - { (char*) "MST7MDT" , 0x099D93 }, - { (char*) "Navajo" , 0x09A6A5 }, - { (char*) "NZ" , 0x09B03D }, - { (char*) "NZ-CHAT" , 0x09B9CE }, - { (char*) "Pacific/Apia" , 0x09C1EE }, - { (char*) "Pacific/Auckland" , 0x09C45E }, - { (char*) "Pacific/Bougainville" , 0x09CE07 }, - { (char*) "Pacific/Chatham" , 0x09CF2B }, - { (char*) "Pacific/Chuuk" , 0x09D75A }, - { (char*) "Pacific/Easter" , 0x09D882 }, - { (char*) "Pacific/Efate" , 0x09E154 }, - { (char*) "Pacific/Enderbury" , 0x09E37A }, - { (char*) "Pacific/Fakaofo" , 0x09E470 }, - { (char*) "Pacific/Fiji" , 0x09E544 }, - { (char*) "Pacific/Funafuti" , 0x09E969 }, - { (char*) "Pacific/Galapagos" , 0x09EA1B }, - { (char*) "Pacific/Gambier" , 0x09EB26 }, - { (char*) "Pacific/Guadalcanal" , 0x09EBE5 }, - { (char*) "Pacific/Guam" , 0x09EC97 }, - { (char*) "Pacific/Honolulu" , 0x09EE91 }, - { (char*) "Pacific/Johnston" , 0x09EFEC }, - { (char*) "Pacific/Kanton" , 0x09F141 }, - { (char*) "Pacific/Kiritimati" , 0x09F246 }, - { (char*) "Pacific/Kosrae" , 0x09F34C }, - { (char*) "Pacific/Kwajalein" , 0x09F4BD }, - { (char*) "Pacific/Majuro" , 0x09F60E }, - { (char*) "Pacific/Marquesas" , 0x09F76D }, - { (char*) "Pacific/Midway" , 0x09F837 }, - { (char*) "Pacific/Nauru" , 0x09F926 }, - { (char*) "Pacific/Niue" , 0x09FA2E }, - { (char*) "Pacific/Norfolk" , 0x09FB05 }, - { (char*) "Pacific/Noumea" , 0x09FE81 }, - { (char*) "Pacific/Pago_Pago" , 0x09FFBD }, - { (char*) "Pacific/Palau" , 0x0A0078 }, - { (char*) "Pacific/Pitcairn" , 0x0A0138 }, - { (char*) "Pacific/Pohnpei" , 0x0A020E }, - { (char*) "Pacific/Ponape" , 0x0A0357 }, - { (char*) "Pacific/Port_Moresby" , 0x0A0492 }, - { (char*) "Pacific/Rarotonga" , 0x0A0575 }, - { (char*) "Pacific/Saipan" , 0x0A07DC }, - { (char*) "Pacific/Samoa" , 0x0A08D4 }, - { (char*) "Pacific/Tahiti" , 0x0A098F }, - { (char*) "Pacific/Tarawa" , 0x0A0A4F }, - { (char*) "Pacific/Tongatapu" , 0x0A0B10 }, - { (char*) "Pacific/Truk" , 0x0A0C90 }, - { (char*) "Pacific/Wake" , 0x0A0DA9 }, - { (char*) "Pacific/Wallis" , 0x0A0E66 }, - { (char*) "Pacific/Yap" , 0x0A0F18 }, - { (char*) "Poland" , 0x0A1031 }, - { (char*) "Portugal" , 0x0A1A9B }, - { (char*) "PRC" , 0x0A2850 }, - { (char*) "PST8PDT" , 0x0A2A8D }, - { (char*) "ROC" , 0x0A339F }, - { (char*) "ROK" , 0x0A36A4 }, - { (char*) "Singapore" , 0x0A3919 }, - { (char*) "Turkey" , 0x0A3AA4 }, - { (char*) "UCT" , 0x0A424B }, - { (char*) "Universal" , 0x0A42C9 }, - { (char*) "US/Alaska" , 0x0A4347 }, - { (char*) "US/Aleutian" , 0x0A4C96 }, - { (char*) "US/Arizona" , 0x0A55D6 }, - { (char*) "US/Central" , 0x0A572A }, - { (char*) "US/East-Indiana" , 0x0A652E }, - { (char*) "US/Eastern" , 0x0A6BBC }, - { (char*) "US/Hawaii" , 0x0A79A8 }, - { (char*) "US/Indiana-Starke" , 0x0A7AFD }, - { (char*) "US/Michigan" , 0x0A8485 }, - { (char*) "US/Mountain" , 0x0A8D47 }, - { (char*) "US/Pacific" , 0x0A96DF }, - { (char*) "US/Samoa" , 0x0AA1FF }, - { (char*) "UTC" , 0x0AA2BA }, - { (char*) "W-SU" , 0x0AA338 }, - { (char*) "WET" , 0x0AA943 }, - { (char*) "Zulu" , 0x0AB0C0 }, + { (char*) "Africa/Gaborone" , 0x003764 }, + { (char*) "Africa/Harare" , 0x00385B }, + { (char*) "Africa/Johannesburg" , 0x0038FC }, + { (char*) "Africa/Juba" , 0x0039FE }, + { (char*) "Africa/Kampala" , 0x003CB1 }, + { (char*) "Africa/Khartoum" , 0x003DB8 }, + { (char*) "Africa/Kigali" , 0x00406B }, + { (char*) "Africa/Kinshasa" , 0x00410C }, + { (char*) "Africa/Lagos" , 0x0041C6 }, + { (char*) "Africa/Libreville" , 0x0042BD }, + { (char*) "Africa/Lome" , 0x00435E }, + { (char*) "Africa/Luanda" , 0x0043FE }, + { (char*) "Africa/Lubumbashi" , 0x0044C5 }, + { (char*) "Africa/Lusaka" , 0x0045A1 }, + { (char*) "Africa/Malabo" , 0x004642 }, + { (char*) "Africa/Maputo" , 0x004705 }, + { (char*) "Africa/Maseru" , 0x0047A6 }, + { (char*) "Africa/Mbabane" , 0x004872 }, + { (char*) "Africa/Mogadishu" , 0x004916 }, + { (char*) "Africa/Monrovia" , 0x0049F7 }, + { (char*) "Africa/Nairobi" , 0x004AD3 }, + { (char*) "Africa/Ndjamena" , 0x004BE8 }, + { (char*) "Africa/Niamey" , 0x004CBB }, + { (char*) "Africa/Nouakchott" , 0x004DA0 }, + { (char*) "Africa/Ouagadougou" , 0x004E7C }, + { (char*) "Africa/Porto-Novo" , 0x004F1C }, + { (char*) "Africa/Sao_Tome" , 0x004FDF }, + { (char*) "Africa/Timbuktu" , 0x0050E9 }, + { (char*) "Africa/Tripoli" , 0x0051C5 }, + { (char*) "Africa/Tunis" , 0x005442 }, + { (char*) "Africa/Windhoek" , 0x0056FF }, + { (char*) "America/Adak" , 0x005AC6 }, + { (char*) "America/Anchorage" , 0x006416 }, + { (char*) "America/Anguilla" , 0x006D78 }, + { (char*) "America/Antigua" , 0x006E18 }, + { (char*) "America/Araguaina" , 0x006EDA }, + { (char*) "America/Argentina/Buenos_Aires" , 0x007263 }, + { (char*) "America/Argentina/Catamarca" , 0x0076B8 }, + { (char*) "America/Argentina/ComodRivadavia" , 0x007B13 }, + { (char*) "America/Argentina/Cordoba" , 0x007F53 }, + { (char*) "America/Argentina/Jujuy" , 0x0083C9 }, + { (char*) "America/Argentina/La_Rioja" , 0x0087F7 }, + { (char*) "America/Argentina/Mendoza" , 0x008C52 }, + { (char*) "America/Argentina/Rio_Gallegos" , 0x00909E }, + { (char*) "America/Argentina/Salta" , 0x0094ED }, + { (char*) "America/Argentina/San_Juan" , 0x009927 }, + { (char*) "America/Argentina/San_Luis" , 0x009D82 }, + { (char*) "America/Argentina/Tucuman" , 0x00A1E9 }, + { (char*) "America/Argentina/Ushuaia" , 0x00A651 }, + { (char*) "America/Aruba" , 0x00AAA6 }, + { (char*) "America/Asuncion" , 0x00AB6C }, + { (char*) "America/Atikokan" , 0x00B374 }, + { (char*) "America/Atka" , 0x00B4F1 }, + { (char*) "America/Bahia" , 0x00BE31 }, + { (char*) "America/Bahia_Banderas" , 0x00C242 }, + { (char*) "America/Barbados" , 0x00C878 }, + { (char*) "America/Belem" , 0x00CA38 }, + { (char*) "America/Belize" , 0x00CC96 }, + { (char*) "America/Blanc-Sablon" , 0x00D2F0 }, + { (char*) "America/Boa_Vista" , 0x00D442 }, + { (char*) "America/Bogota" , 0x00D6CD }, + { (char*) "America/Boise" , 0x00D7CF }, + { (char*) "America/Buenos_Aires" , 0x00E155 }, + { (char*) "America/Cambridge_Bay" , 0x00E595 }, + { (char*) "America/Campo_Grande" , 0x00EDD9 }, + { (char*) "America/Cancun" , 0x00F39B }, + { (char*) "America/Caracas" , 0x00F6D9 }, + { (char*) "America/Catamarca" , 0x00F7ED }, + { (char*) "America/Cayenne" , 0x00FC2D }, + { (char*) "America/Cayman" , 0x00FCFF }, + { (char*) "America/Chicago" , 0x00FDC1 }, + { (char*) "America/Chihuahua" , 0x010BD9 }, + { (char*) "America/Coral_Harbour" , 0x0111D7 }, + { (char*) "America/Cordoba" , 0x011333 }, + { (char*) "America/Costa_Rica" , 0x011773 }, + { (char*) "America/Creston" , 0x0118BB }, + { (char*) "America/Cuiaba" , 0x0119A9 }, + { (char*) "America/Curacao" , 0x011F48 }, + { (char*) "America/Danmarkshavn" , 0x01200E }, + { (char*) "America/Dawson" , 0x0122EE }, + { (char*) "America/Dawson_Creek" , 0x01295A }, + { (char*) "America/Denver" , 0x012DA0 }, + { (char*) "America/Detroit" , 0x01374D }, + { (char*) "America/Dominica" , 0x014028 }, + { (char*) "America/Edmonton" , 0x0140C8 }, + { (char*) "America/Eirunepe" , 0x014A0D }, + { (char*) "America/El_Salvador" , 0x014CB8 }, + { (char*) "America/Ensenada" , 0x014DA4 }, + { (char*) "America/Fort_Nelson" , 0x0156D6 }, + { (char*) "America/Fort_Wayne" , 0x015FB6 }, + { (char*) "America/Fortaleza" , 0x016644 }, + { (char*) "America/Glace_Bay" , 0x016942 }, + { (char*) "America/Godthab" , 0x0171F9 }, + { (char*) "America/Goose_Bay" , 0x01795B }, + { (char*) "America/Grand_Turk" , 0x018611 }, + { (char*) "America/Grenada" , 0x018D47 }, + { (char*) "America/Guadeloupe" , 0x018DE7 }, + { (char*) "America/Guatemala" , 0x018E87 }, + { (char*) "America/Guayaquil" , 0x018FAB }, + { (char*) "America/Guyana" , 0x0190BF }, + { (char*) "America/Halifax" , 0x0191D1 }, + { (char*) "America/Havana" , 0x019F5B }, + { (char*) "America/Hermosillo" , 0x01A8D7 }, + { (char*) "America/Indiana/Indianapolis" , 0x01AAA2 }, + { (char*) "America/Indiana/Knox" , 0x01B149 }, + { (char*) "America/Indiana/Marengo" , 0x01BAE6 }, + { (char*) "America/Indiana/Petersburg" , 0x01C1C3 }, + { (char*) "America/Indiana/Tell_City" , 0x01C952 }, + { (char*) "America/Indiana/Vevay" , 0x01D006 }, + { (char*) "America/Indiana/Vincennes" , 0x01D5B2 }, + { (char*) "America/Indiana/Winamac" , 0x01DC78 }, + { (char*) "America/Indianapolis" , 0x01E38C }, + { (char*) "America/Inuvik" , 0x01EA1A }, + { (char*) "America/Iqaluit" , 0x01F1A0 }, + { (char*) "America/Jamaica" , 0x01F9BA }, + { (char*) "America/Jujuy" , 0x01FBA8 }, + { (char*) "America/Juneau" , 0x01FFCC }, + { (char*) "America/Kentucky/Louisville" , 0x02091D }, + { (char*) "America/Kentucky/Monticello" , 0x02141B }, + { (char*) "America/Knox_IN" , 0x021D6B }, + { (char*) "America/Kralendijk" , 0x0226F3 }, + { (char*) "America/La_Paz" , 0x0227B9 }, + { (char*) "America/Lima" , 0x0228AD }, + { (char*) "America/Los_Angeles" , 0x022A4F }, + { (char*) "America/Louisville" , 0x023576 }, + { (char*) "America/Lower_Princes" , 0x024056 }, + { (char*) "America/Maceio" , 0x02411C }, + { (char*) "America/Managua" , 0x024420 }, + { (char*) "America/Manaus" , 0x0245DA }, + { (char*) "America/Marigot" , 0x024851 }, + { (char*) "America/Martinique" , 0x0248F1 }, + { (char*) "America/Matamoros" , 0x0249E5 }, + { (char*) "America/Mazatlan" , 0x024F9D }, + { (char*) "America/Mendoza" , 0x0255D4 }, + { (char*) "America/Menominee" , 0x025A14 }, + { (char*) "America/Merida" , 0x026321 }, + { (char*) "America/Metlakatla" , 0x0268DB }, + { (char*) "America/Mexico_City" , 0x026E8D }, + { (char*) "America/Miquelon" , 0x0274D5 }, + { (char*) "America/Moncton" , 0x027B63 }, + { (char*) "America/Monterrey" , 0x0287D9 }, + { (char*) "America/Montevideo" , 0x028D98 }, + { (char*) "America/Montreal" , 0x02938A }, + { (char*) "America/Montserrat" , 0x02A13C }, + { (char*) "America/Nassau" , 0x02A1DC }, + { (char*) "America/New_York" , 0x02AB3C }, + { (char*) "America/Nipigon" , 0x02B93C }, + { (char*) "America/Nome" , 0x02C1B3 }, + { (char*) "America/Noronha" , 0x02CB0B }, + { (char*) "America/North_Dakota/Beulah" , 0x02CDF3 }, + { (char*) "America/North_Dakota/Center" , 0x02D760 }, + { (char*) "America/North_Dakota/New_Salem" , 0x02E0CD }, + { (char*) "America/Nuuk" , 0x02EA40 }, + { (char*) "America/Ojinaga" , 0x02F1B8 }, + { (char*) "America/Panama" , 0x02F7B8 }, + { (char*) "America/Pangnirtung" , 0x02F87A }, + { (char*) "America/Paramaribo" , 0x0300CE }, + { (char*) "America/Phoenix" , 0x0301E0 }, + { (char*) "America/Port-au-Prince" , 0x030351 }, + { (char*) "America/Port_of_Spain" , 0x0308F7 }, + { (char*) "America/Porto_Acre" , 0x030997 }, + { (char*) "America/Porto_Velho" , 0x030C17 }, + { (char*) "America/Puerto_Rico" , 0x030E6B }, + { (char*) "America/Punta_Arenas" , 0x030F6D }, + { (char*) "America/Rainy_River" , 0x031709 }, + { (char*) "America/Rankin_Inlet" , 0x031F81 }, + { (char*) "America/Recife" , 0x032707 }, + { (char*) "America/Regina" , 0x0329E9 }, + { (char*) "America/Resolute" , 0x032DDE }, + { (char*) "America/Rio_Branco" , 0x033565 }, + { (char*) "America/Rosario" , 0x0337E9 }, + { (char*) "America/Santa_Isabel" , 0x033C29 }, + { (char*) "America/Santarem" , 0x03455B }, + { (char*) "America/Santiago" , 0x0347CC }, + { (char*) "America/Santo_Domingo" , 0x0351CB }, + { (char*) "America/Sao_Paulo" , 0x0353A1 }, + { (char*) "America/Scoresbysund" , 0x035987 }, + { (char*) "America/Shiprock" , 0x03612C }, + { (char*) "America/Sitka" , 0x036AC4 }, + { (char*) "America/St_Barthelemy" , 0x0373FC }, + { (char*) "America/St_Johns" , 0x03749C }, + { (char*) "America/St_Kitts" , 0x038311 }, + { (char*) "America/St_Lucia" , 0x0383B1 }, + { (char*) "America/St_Thomas" , 0x038473 }, + { (char*) "America/St_Vincent" , 0x038513 }, + { (char*) "America/Swift_Current" , 0x0385D5 }, + { (char*) "America/Tegucigalpa" , 0x038823 }, + { (char*) "America/Thule" , 0x03892B }, + { (char*) "America/Thunder_Bay" , 0x038F23 }, + { (char*) "America/Tijuana" , 0x0397E3 }, + { (char*) "America/Toronto" , 0x03A136 }, + { (char*) "America/Tortola" , 0x03AF05 }, + { (char*) "America/Vancouver" , 0x03AFA5 }, + { (char*) "America/Virgin" , 0x03BB16 }, + { (char*) "America/Whitehorse" , 0x03BBB6 }, + { (char*) "America/Winnipeg" , 0x03C222 }, + { (char*) "America/Yakutat" , 0x03CD7F }, + { (char*) "America/Yellowknife" , 0x03D69C }, + { (char*) "Antarctica/Casey" , 0x03DE6D }, + { (char*) "Antarctica/Davis" , 0x03DFFE }, + { (char*) "Antarctica/DumontDUrville" , 0x03E138 }, + { (char*) "Antarctica/Macquarie" , 0x03E216 }, + { (char*) "Antarctica/Mawson" , 0x03EB06 }, + { (char*) "Antarctica/McMurdo" , 0x03EBDF }, + { (char*) "Antarctica/Palmer" , 0x03F3DA }, + { (char*) "Antarctica/Rothera" , 0x03F976 }, + { (char*) "Antarctica/South_Pole" , 0x03FA2D }, + { (char*) "Antarctica/Syowa" , 0x040202 }, + { (char*) "Antarctica/Troll" , 0x0402B8 }, + { (char*) "Antarctica/Vostok" , 0x040753 }, + { (char*) "Arctic/Longyearbyen" , 0x04080A }, + { (char*) "Asia/Aden" , 0x0410CA }, + { (char*) "Asia/Almaty" , 0x04117B }, + { (char*) "Asia/Amman" , 0x041583 }, + { (char*) "Asia/Anadyr" , 0x041CCC }, + { (char*) "Asia/Aqtau" , 0x04218F }, + { (char*) "Asia/Aqtobe" , 0x042587 }, + { (char*) "Asia/Ashgabat" , 0x042993 }, + { (char*) "Asia/Ashkhabad" , 0x042C0A }, + { (char*) "Asia/Atyrau" , 0x042E81 }, + { (char*) "Asia/Baghdad" , 0x043281 }, + { (char*) "Asia/Bahrain" , 0x043664 }, + { (char*) "Asia/Baku" , 0x04375D }, + { (char*) "Asia/Bangkok" , 0x043C34 }, + { (char*) "Asia/Barnaul" , 0x043D07 }, + { (char*) "Asia/Beirut" , 0x0441E6 }, + { (char*) "Asia/Bishkek" , 0x044A5C }, + { (char*) "Asia/Brunei" , 0x044E3F }, + { (char*) "Asia/Calcutta" , 0x044F16 }, + { (char*) "Asia/Chita" , 0x04503F }, + { (char*) "Asia/Choibalsan" , 0x045524 }, + { (char*) "Asia/Chongqing" , 0x0458F7 }, + { (char*) "Asia/Chungking" , 0x045B34 }, + { (char*) "Asia/Colombo" , 0x045D71 }, + { (char*) "Asia/Dacca" , 0x045EF1 }, + { (char*) "Asia/Damascus" , 0x04604E }, + { (char*) "Asia/Dhaka" , 0x046950 }, + { (char*) "Asia/Dili" , 0x046AAD }, + { (char*) "Asia/Dubai" , 0x046B9C }, + { (char*) "Asia/Dushanbe" , 0x046C4D }, + { (char*) "Asia/Famagusta" , 0x046EA8 }, + { (char*) "Asia/Gaza" , 0x0476AF }, + { (char*) "Asia/Harbin" , 0x04803B }, + { (char*) "Asia/Hebron" , 0x048278 }, + { (char*) "Asia/Ho_Chi_Minh" , 0x048C1F }, + { (char*) "Asia/Hong_Kong" , 0x048D8A }, + { (char*) "Asia/Hovd" , 0x049267 }, + { (char*) "Asia/Irkutsk" , 0x049619 }, + { (char*) "Asia/Istanbul" , 0x049B1A }, + { (char*) "Asia/Jakarta" , 0x04A2C1 }, + { (char*) "Asia/Jayapura" , 0x04A459 }, + { (char*) "Asia/Jerusalem" , 0x04A578 }, + { (char*) "Asia/Kabul" , 0x04AED8 }, + { (char*) "Asia/Kamchatka" , 0x04AFB4 }, + { (char*) "Asia/Karachi" , 0x04B460 }, + { (char*) "Asia/Kashgar" , 0x04B5E7 }, + { (char*) "Asia/Kathmandu" , 0x04B698 }, + { (char*) "Asia/Katmandu" , 0x04B778 }, + { (char*) "Asia/Khandyga" , 0x04B858 }, + { (char*) "Asia/Kolkata" , 0x04BD79 }, + { (char*) "Asia/Krasnoyarsk" , 0x04BEA2 }, + { (char*) "Asia/Kuala_Lumpur" , 0x04C37E }, + { (char*) "Asia/Kuching" , 0x04C51D }, + { (char*) "Asia/Kuwait" , 0x04C71A }, + { (char*) "Asia/Macao" , 0x04C7CB }, + { (char*) "Asia/Macau" , 0x04CCA2 }, + { (char*) "Asia/Magadan" , 0x04D179 }, + { (char*) "Asia/Makassar" , 0x04D65B }, + { (char*) "Asia/Manila" , 0x04D7AE }, + { (char*) "Asia/Muscat" , 0x04D902 }, + { (char*) "Asia/Nicosia" , 0x04D9B3 }, + { (char*) "Asia/Novokuznetsk" , 0x04E1A4 }, + { (char*) "Asia/Novosibirsk" , 0x04E64E }, + { (char*) "Asia/Omsk" , 0x04EB33 }, + { (char*) "Asia/Oral" , 0x04F003 }, + { (char*) "Asia/Phnom_Penh" , 0x04F40B }, + { (char*) "Asia/Pontianak" , 0x04F53E }, + { (char*) "Asia/Pyongyang" , 0x04F6C1 }, + { (char*) "Asia/Qatar" , 0x04F7BA }, + { (char*) "Asia/Qostanay" , 0x04F88D }, + { (char*) "Asia/Qyzylorda" , 0x04FCA6 }, + { (char*) "Asia/Rangoon" , 0x0500D0 }, + { (char*) "Asia/Riyadh" , 0x0501E8 }, + { (char*) "Asia/Saigon" , 0x050299 }, + { (char*) "Asia/Sakhalin" , 0x050404 }, + { (char*) "Asia/Samarkand" , 0x0508DA }, + { (char*) "Asia/Seoul" , 0x050B38 }, + { (char*) "Asia/Shanghai" , 0x050DAD }, + { (char*) "Asia/Singapore" , 0x050FF6 }, + { (char*) "Asia/Srednekolymsk" , 0x051181 }, + { (char*) "Asia/Taipei" , 0x051667 }, + { (char*) "Asia/Tashkent" , 0x05196C }, + { (char*) "Asia/Tbilisi" , 0x051BD8 }, + { (char*) "Asia/Tehran" , 0x051FEF }, + { (char*) "Asia/Tel_Aviv" , 0x0524E9 }, + { (char*) "Asia/Thimbu" , 0x052E49 }, + { (char*) "Asia/Thimphu" , 0x052F20 }, + { (char*) "Asia/Tokyo" , 0x052FF7 }, + { (char*) "Asia/Tomsk" , 0x053138 }, + { (char*) "Asia/Ujung_Pandang" , 0x053617 }, + { (char*) "Asia/Ulaanbaatar" , 0x053721 }, + { (char*) "Asia/Ulan_Bator" , 0x053ABD }, + { (char*) "Asia/Urumqi" , 0x053E44 }, + { (char*) "Asia/Ust-Nera" , 0x053F02 }, + { (char*) "Asia/Vientiane" , 0x054406 }, + { (char*) "Asia/Vladivostok" , 0x054555 }, + { (char*) "Asia/Yakutsk" , 0x054A2C }, + { (char*) "Asia/Yangon" , 0x054F02 }, + { (char*) "Asia/Yekaterinburg" , 0x05501A }, + { (char*) "Asia/Yerevan" , 0x05550F }, + { (char*) "Atlantic/Azores" , 0x05599A }, + { (char*) "Atlantic/Bermuda" , 0x056764 }, + { (char*) "Atlantic/Canary" , 0x0570CC }, + { (char*) "Atlantic/Cape_Verde" , 0x05784F }, + { (char*) "Atlantic/Faeroe" , 0x057969 }, + { (char*) "Atlantic/Faroe" , 0x05808C }, + { (char*) "Atlantic/Jan_Mayen" , 0x0587AF }, + { (char*) "Atlantic/Madeira" , 0x05906F }, + { (char*) "Atlantic/Reykjavik" , 0x059E39 }, + { (char*) "Atlantic/South_Georgia" , 0x05A2CF }, + { (char*) "Atlantic/St_Helena" , 0x05A37F }, + { (char*) "Atlantic/Stanley" , 0x05A441 }, + { (char*) "Australia/ACT" , 0x05A90B }, + { (char*) "Australia/Adelaide" , 0x05B1A5 }, + { (char*) "Australia/Brisbane" , 0x05BA60 }, + { (char*) "Australia/Broken_Hill" , 0x05BC26 }, + { (char*) "Australia/Canberra" , 0x05C503 }, + { (char*) "Australia/Currie" , 0x05CD9D }, + { (char*) "Australia/Darwin" , 0x05D6DF }, + { (char*) "Australia/Eucla" , 0x05D842 }, + { (char*) "Australia/Hobart" , 0x05DA3D }, + { (char*) "Australia/LHI" , 0x05E387 }, + { (char*) "Australia/Lindeman" , 0x05EAD7 }, + { (char*) "Australia/Lord_Howe" , 0x05ECDD }, + { (char*) "Australia/Melbourne" , 0x05F43D }, + { (char*) "Australia/North" , 0x05FCDF }, + { (char*) "Australia/NSW" , 0x05FE30 }, + { (char*) "Australia/Perth" , 0x0606CA }, + { (char*) "Australia/Queensland" , 0x0608B2 }, + { (char*) "Australia/South" , 0x060A61 }, + { (char*) "Australia/Sydney" , 0x06130D }, + { (char*) "Australia/Tasmania" , 0x061BC3 }, + { (char*) "Australia/Victoria" , 0x062505 }, + { (char*) "Australia/West" , 0x062D9F }, + { (char*) "Australia/Yancowinna" , 0x062F69 }, + { (char*) "Brazil/Acre" , 0x06382A }, + { (char*) "Brazil/DeNoronha" , 0x063AAA }, + { (char*) "Brazil/East" , 0x063D82 }, + { (char*) "Brazil/West" , 0x064332 }, + { (char*) "Canada/Atlantic" , 0x06459A }, + { (char*) "Canada/Central" , 0x065306 }, + { (char*) "Canada/Eastern" , 0x065E46 }, + { (char*) "Canada/Mountain" , 0x066BF8 }, + { (char*) "Canada/Newfoundland" , 0x067520 }, + { (char*) "Canada/Pacific" , 0x068373 }, + { (char*) "Canada/Saskatchewan" , 0x068ECB }, + { (char*) "Canada/Yukon" , 0x0692AB }, + { (char*) "CET" , 0x069905 }, + { (char*) "Chile/Continental" , 0x06A13F }, + { (char*) "Chile/EasterIsland" , 0x06AB2C }, + { (char*) "CST6CDT" , 0x06B3F1 }, + { (char*) "Cuba" , 0x06BD03 }, + { (char*) "EET" , 0x06C67F }, + { (char*) "Egypt" , 0x06CDFF }, + { (char*) "Eire" , 0x06D5AE }, + { (char*) "EST" , 0x06E35E }, + { (char*) "EST5EDT" , 0x06E3DC }, + { (char*) "Etc/GMT" , 0x06ECEE }, + { (char*) "Etc/GMT+0" , 0x06ED6C }, + { (char*) "Etc/GMT+1" , 0x06EDEA }, + { (char*) "Etc/GMT+10" , 0x06EE6A }, + { (char*) "Etc/GMT+11" , 0x06EEEB }, + { (char*) "Etc/GMT+12" , 0x06EF6C }, + { (char*) "Etc/GMT+2" , 0x06EFED }, + { (char*) "Etc/GMT+3" , 0x06F06D }, + { (char*) "Etc/GMT+4" , 0x06F0ED }, + { (char*) "Etc/GMT+5" , 0x06F16D }, + { (char*) "Etc/GMT+6" , 0x06F1ED }, + { (char*) "Etc/GMT+7" , 0x06F26D }, + { (char*) "Etc/GMT+8" , 0x06F2ED }, + { (char*) "Etc/GMT+9" , 0x06F36D }, + { (char*) "Etc/GMT-0" , 0x06F3ED }, + { (char*) "Etc/GMT-1" , 0x06F46B }, + { (char*) "Etc/GMT-10" , 0x06F4EC }, + { (char*) "Etc/GMT-11" , 0x06F56E }, + { (char*) "Etc/GMT-12" , 0x06F5F0 }, + { (char*) "Etc/GMT-13" , 0x06F672 }, + { (char*) "Etc/GMT-14" , 0x06F6F4 }, + { (char*) "Etc/GMT-2" , 0x06F776 }, + { (char*) "Etc/GMT-3" , 0x06F7F7 }, + { (char*) "Etc/GMT-4" , 0x06F878 }, + { (char*) "Etc/GMT-5" , 0x06F8F9 }, + { (char*) "Etc/GMT-6" , 0x06F97A }, + { (char*) "Etc/GMT-7" , 0x06F9FB }, + { (char*) "Etc/GMT-8" , 0x06FA7C }, + { (char*) "Etc/GMT-9" , 0x06FAFD }, + { (char*) "Etc/GMT0" , 0x06FB7E }, + { (char*) "Etc/Greenwich" , 0x06FBFC }, + { (char*) "Etc/UCT" , 0x06FC7A }, + { (char*) "Etc/Universal" , 0x06FCF8 }, + { (char*) "Etc/UTC" , 0x06FD76 }, + { (char*) "Etc/Zulu" , 0x06FDF4 }, + { (char*) "Europe/Amsterdam" , 0x06FE72 }, + { (char*) "Europe/Andorra" , 0x0709DC }, + { (char*) "Europe/Astrakhan" , 0x0710B6 }, + { (char*) "Europe/Athens" , 0x071561 }, + { (char*) "Europe/Belfast" , 0x071E43 }, + { (char*) "Europe/Belgrade" , 0x072C9F }, + { (char*) "Europe/Berlin" , 0x07342B }, + { (char*) "Europe/Bratislava" , 0x073D45 }, + { (char*) "Europe/Brussels" , 0x07464E }, + { (char*) "Europe/Bucharest" , 0x0751CF }, + { (char*) "Europe/Budapest" , 0x075A63 }, + { (char*) "Europe/Busingen" , 0x0763AF }, + { (char*) "Europe/Chisinau" , 0x076B38 }, + { (char*) "Europe/Copenhagen" , 0x07749A }, + { (char*) "Europe/Dublin" , 0x077CFF }, + { (char*) "Europe/Gibraltar" , 0x078AAF }, + { (char*) "Europe/Guernsey" , 0x0796B7 }, + { (char*) "Europe/Helsinki" , 0x07A557 }, + { (char*) "Europe/Isle_of_Man" , 0x07ACCF }, + { (char*) "Europe/Istanbul" , 0x07BB1B }, + { (char*) "Europe/Jersey" , 0x07C2C2 }, + { (char*) "Europe/Kaliningrad" , 0x07D162 }, + { (char*) "Europe/Kiev" , 0x07D757 }, + { (char*) "Europe/Kirov" , 0x07DFAB }, + { (char*) "Europe/Kyiv" , 0x07E446 }, + { (char*) "Europe/Lisbon" , 0x07ECAE }, + { (char*) "Europe/Ljubljana" , 0x07FA76 }, + { (char*) "Europe/London" , 0x080202 }, + { (char*) "Europe/Luxembourg" , 0x08105E }, + { (char*) "Europe/Madrid" , 0x081BEC }, + { (char*) "Europe/Malta" , 0x08263E }, + { (char*) "Europe/Mariehamn" , 0x083086 }, + { (char*) "Europe/Minsk" , 0x0837FE }, + { (char*) "Europe/Monaco" , 0x083D33 }, + { (char*) "Europe/Moscow" , 0x0848BF }, + { (char*) "Europe/Nicosia" , 0x084EDE }, + { (char*) "Europe/Oslo" , 0x0856BC }, + { (char*) "Europe/Paris" , 0x085F7C }, + { (char*) "Europe/Podgorica" , 0x086B1A }, + { (char*) "Europe/Prague" , 0x0872A6 }, + { (char*) "Europe/Riga" , 0x087BAF }, + { (char*) "Europe/Rome" , 0x088451 }, + { (char*) "Europe/Samara" , 0x088EAE }, + { (char*) "Europe/San_Marino" , 0x089392 }, + { (char*) "Europe/Sarajevo" , 0x089DEF }, + { (char*) "Europe/Saratov" , 0x08A57B }, + { (char*) "Europe/Simferopol" , 0x08AA36 }, + { (char*) "Europe/Skopje" , 0x08B005 }, + { (char*) "Europe/Sofia" , 0x08B791 }, + { (char*) "Europe/Stockholm" , 0x08BFBA }, + { (char*) "Europe/Tallinn" , 0x08C73B }, + { (char*) "Europe/Tirane" , 0x08CFAB }, + { (char*) "Europe/Tiraspol" , 0x08D7DB }, + { (char*) "Europe/Ulyanovsk" , 0x08E13D }, + { (char*) "Europe/Uzhgorod" , 0x08E64E }, + { (char*) "Europe/Vaduz" , 0x08EEA2 }, + { (char*) "Europe/Vatican" , 0x08F60E }, + { (char*) "Europe/Vienna" , 0x09006B }, + { (char*) "Europe/Vilnius" , 0x09090F }, + { (char*) "Europe/Volgograd" , 0x09118D }, + { (char*) "Europe/Warsaw" , 0x091638 }, + { (char*) "Europe/Zagreb" , 0x0920A2 }, + { (char*) "Europe/Zaporozhye" , 0x09282E }, + { (char*) "Europe/Zurich" , 0x093082 }, + { (char*) "Factory" , 0x093803 }, + { (char*) "GB" , 0x093883 }, + { (char*) "GB-Eire" , 0x0946DF }, + { (char*) "GMT" , 0x09553B }, + { (char*) "GMT+0" , 0x0955B9 }, + { (char*) "GMT-0" , 0x095637 }, + { (char*) "GMT0" , 0x0956B5 }, + { (char*) "Greenwich" , 0x095733 }, + { (char*) "Hongkong" , 0x0957B1 }, + { (char*) "HST" , 0x095C8E }, + { (char*) "Iceland" , 0x095D0D }, + { (char*) "Indian/Antananarivo" , 0x0961A3 }, + { (char*) "Indian/Chagos" , 0x09628A }, + { (char*) "Indian/Christmas" , 0x09635D }, + { (char*) "Indian/Cocos" , 0x09640E }, + { (char*) "Indian/Comoro" , 0x0964C8 }, + { (char*) "Indian/Kerguelen" , 0x096569 }, + { (char*) "Indian/Mahe" , 0x09661A }, + { (char*) "Indian/Maldives" , 0x0966CB }, + { (char*) "Indian/Mauritius" , 0x09679E }, + { (char*) "Indian/Mayotte" , 0x09689B }, + { (char*) "Indian/Reunion" , 0x09693C }, + { (char*) "Iran" , 0x0969ED }, + { (char*) "Israel" , 0x096EE7 }, + { (char*) "Jamaica" , 0x097847 }, + { (char*) "Japan" , 0x097A35 }, + { (char*) "Kwajalein" , 0x097B76 }, + { (char*) "Libya" , 0x097CBE }, + { (char*) "MET" , 0x097F3B }, + { (char*) "Mexico/BajaNorte" , 0x098775 }, + { (char*) "Mexico/BajaSur" , 0x0990A7 }, + { (char*) "Mexico/General" , 0x0996A9 }, + { (char*) "MST" , 0x099CE5 }, + { (char*) "MST7MDT" , 0x099D63 }, + { (char*) "Navajo" , 0x09A675 }, + { (char*) "NZ" , 0x09B00D }, + { (char*) "NZ-CHAT" , 0x09B99E }, + { (char*) "Pacific/Apia" , 0x09C1BE }, + { (char*) "Pacific/Auckland" , 0x09C42E }, + { (char*) "Pacific/Bougainville" , 0x09CDD7 }, + { (char*) "Pacific/Chatham" , 0x09CEFB }, + { (char*) "Pacific/Chuuk" , 0x09D72A }, + { (char*) "Pacific/Easter" , 0x09D852 }, + { (char*) "Pacific/Efate" , 0x09E124 }, + { (char*) "Pacific/Enderbury" , 0x09E34A }, + { (char*) "Pacific/Fakaofo" , 0x09E440 }, + { (char*) "Pacific/Fiji" , 0x09E514 }, + { (char*) "Pacific/Funafuti" , 0x09E939 }, + { (char*) "Pacific/Galapagos" , 0x09E9EB }, + { (char*) "Pacific/Gambier" , 0x09EAF6 }, + { (char*) "Pacific/Guadalcanal" , 0x09EBB5 }, + { (char*) "Pacific/Guam" , 0x09EC67 }, + { (char*) "Pacific/Honolulu" , 0x09EE61 }, + { (char*) "Pacific/Johnston" , 0x09EFBC }, + { (char*) "Pacific/Kanton" , 0x09F111 }, + { (char*) "Pacific/Kiritimati" , 0x09F216 }, + { (char*) "Pacific/Kosrae" , 0x09F31C }, + { (char*) "Pacific/Kwajalein" , 0x09F48D }, + { (char*) "Pacific/Majuro" , 0x09F5DE }, + { (char*) "Pacific/Marquesas" , 0x09F73D }, + { (char*) "Pacific/Midway" , 0x09F807 }, + { (char*) "Pacific/Nauru" , 0x09F8FA }, + { (char*) "Pacific/Niue" , 0x09FA02 }, + { (char*) "Pacific/Norfolk" , 0x09FAD9 }, + { (char*) "Pacific/Noumea" , 0x09FE55 }, + { (char*) "Pacific/Pago_Pago" , 0x09FF91 }, + { (char*) "Pacific/Palau" , 0x0A004C }, + { (char*) "Pacific/Pitcairn" , 0x0A010C }, + { (char*) "Pacific/Pohnpei" , 0x0A01E2 }, + { (char*) "Pacific/Ponape" , 0x0A032B }, + { (char*) "Pacific/Port_Moresby" , 0x0A0466 }, + { (char*) "Pacific/Rarotonga" , 0x0A0549 }, + { (char*) "Pacific/Saipan" , 0x0A07B0 }, + { (char*) "Pacific/Samoa" , 0x0A099C }, + { (char*) "Pacific/Tahiti" , 0x0A0A57 }, + { (char*) "Pacific/Tarawa" , 0x0A0B17 }, + { (char*) "Pacific/Tongatapu" , 0x0A0BD8 }, + { (char*) "Pacific/Truk" , 0x0A0D58 }, + { (char*) "Pacific/Wake" , 0x0A0E71 }, + { (char*) "Pacific/Wallis" , 0x0A0F2E }, + { (char*) "Pacific/Yap" , 0x0A0FE0 }, + { (char*) "Poland" , 0x0A10F9 }, + { (char*) "Portugal" , 0x0A1B63 }, + { (char*) "PRC" , 0x0A2918 }, + { (char*) "PST8PDT" , 0x0A2B55 }, + { (char*) "ROC" , 0x0A3467 }, + { (char*) "ROK" , 0x0A376C }, + { (char*) "Singapore" , 0x0A39E1 }, + { (char*) "Turkey" , 0x0A3B6C }, + { (char*) "UCT" , 0x0A4313 }, + { (char*) "Universal" , 0x0A4391 }, + { (char*) "US/Alaska" , 0x0A440F }, + { (char*) "US/Aleutian" , 0x0A4D5E }, + { (char*) "US/Arizona" , 0x0A569E }, + { (char*) "US/Central" , 0x0A57F2 }, + { (char*) "US/East-Indiana" , 0x0A65F6 }, + { (char*) "US/Eastern" , 0x0A6C84 }, + { (char*) "US/Hawaii" , 0x0A7A70 }, + { (char*) "US/Indiana-Starke" , 0x0A7BC5 }, + { (char*) "US/Michigan" , 0x0A854D }, + { (char*) "US/Mountain" , 0x0A8E0F }, + { (char*) "US/Pacific" , 0x0A97A7 }, + { (char*) "US/Samoa" , 0x0AA2C7 }, + { (char*) "UTC" , 0x0AA382 }, + { (char*) "W-SU" , 0x0AA400 }, + { (char*) "WET" , 0x0AAA0B }, + { (char*) "Zulu" , 0x0AB188 }, }; -const unsigned char timelib_timezone_db_data_builtin[700734] = { +const unsigned char timelib_timezone_db_data_builtin[700934] = { /* Africa/Abidjan */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -24755,37 +24766,34 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { /* Africa/Freetown */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x53, 0x4C, 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, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x00, 0x95, 0xB7, 0xBF, 0x6C, 0xBA, 0x3E, 0xE0, 0x90, 0xBA, 0xDE, 0x61, 0x60, 0xBB, 0xA8, 0x1B, 0x90, 0xBC, 0xBF, 0x94, 0xE0, 0xBD, 0x89, 0x4F, 0x10, 0xBE, 0xA0, 0xC8, 0x60, 0xBF, 0x6A, 0x82, 0x90, 0xC0, 0x83, 0x4D, 0x60, 0xC1, 0x4D, 0x07, 0x90, 0xC2, 0x64, 0x80, 0xE0, 0xC3, 0x2E, 0x3B, 0x10, 0xC4, 0x45, 0xB4, 0x60, 0xC5, 0x0F, 0x6E, 0x90, 0xC6, 0x77, 0x53, 0x60, 0xC6, 0xF0, 0xA2, 0x10, -0xC6, 0xF5, 0xE3, 0x60, 0xCB, 0x34, 0x3C, 0x10, 0x7F, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0x02, 0x03, -0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x04, 0x04, -0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x04, 0xFF, 0xFF, 0xF6, 0xA0, -0x01, 0x08, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x0E, 0x00, 0x00, 0x04, 0xB0, 0x01, 0x12, 0x4C, 0x4D, -0x54, 0x00, 0x46, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x30, 0x34, 0x30, 0x00, 0x2D, 0x30, 0x31, 0x00, -0x2B, 0x30, 0x31, 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, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x16, -0xFF, 0xFF, 0xFF, 0xFF, 0x5A, 0x7A, 0xA8, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0xB7, 0xBF, 0x6C, -0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0x3E, 0xE0, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xDE, 0x61, 0x60, -0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0xA8, 0x1B, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xBF, 0x94, 0xE0, -0xFF, 0xFF, 0xFF, 0xFF, 0xBD, 0x89, 0x4F, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xA0, 0xC8, 0x60, -0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x6A, 0x82, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x83, 0x4D, 0x60, -0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0x4D, 0x07, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xC2, 0x64, 0x80, 0xE0, -0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x2E, 0x3B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xC4, 0x45, 0xB4, 0x60, -0xFF, 0xFF, 0xFF, 0xFF, 0xC5, 0x0F, 0x6E, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x77, 0x53, 0x60, -0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0xF0, 0xA2, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0xF5, 0xE3, 0x60, -0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x34, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, -0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, -0x02, 0x03, 0x04, 0x04, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x04, -0xFF, 0xFF, 0xF6, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x0E, 0x00, 0x00, 0x04, 0xB0, -0x01, 0x12, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x30, 0x34, 0x30, 0x00, -0x2D, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x0A, 0x58, 0x58, 0x58, 0x2D, 0x30, 0x3A, 0x34, -0x30, 0x3C, 0x2B, 0x30, 0x31, 0x3E, 0x2D, 0x30, 0x3A, 0x32, 0x30, 0x2C, 0x30, 0x2F, 0x30, 0x2C, -0x4A, 0x33, 0x36, 0x35, 0x2F, 0x32, 0x33, 0x3A, 0x34, 0x30, 0x0A, 0x00, 0x96, 0x4C, 0x90, 0x00, -0xFE, 0x70, 0xB8, 0x00, 0x00, 0x00, 0x00, +0xC6, 0xF5, 0xE3, 0x60, 0xCB, 0x34, 0x3C, 0x10, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x04, 0xFF, 0xFF, 0xF3, 0x94, 0x00, +0x00, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x04, 0xFF, 0xFF, 0xF6, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xF1, +0xF0, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4D, 0x54, +0x00, 0x2D, 0x30, 0x30, 0x34, 0x30, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x47, 0x4D, 0x54, 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, 0x13, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0x5A, +0x7A, 0xA8, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0xB7, 0xBF, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, +0x3E, 0xE0, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xDE, 0x61, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, +0xA8, 0x1B, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xBF, 0x94, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xBD, +0x89, 0x4F, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xA0, 0xC8, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, +0x6A, 0x82, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x83, 0x4D, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, +0x4D, 0x07, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xC2, 0x64, 0x80, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, +0x2E, 0x3B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xC4, 0x45, 0xB4, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5, +0x0F, 0x6E, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x77, 0x53, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, +0xF0, 0xA2, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0xF5, 0xE3, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, +0x34, 0x3C, 0x10, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, +0x03, 0x02, 0x03, 0x02, 0x03, 0x04, 0xFF, 0xFF, 0xF3, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0x94, +0x00, 0x04, 0xFF, 0xFF, 0xF6, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x0E, 0x00, 0x00, +0x00, 0x00, 0x00, 0x12, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x30, 0x34, +0x30, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x0A, 0x47, 0x4D, 0x54, 0x30, 0x0A, +0x00, 0x96, 0x4C, 0x90, 0x00, 0xFE, 0x70, 0xB8, 0x00, 0x00, 0x00, 0x00, /* Africa/Gaborone */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x42, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -42845,15 +42853,15 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x56, 0x29, 0x5C, 0x60, 0x56, 0xF5, 0xC2, 0xF0, 0x58, 0x13, 0xCA, 0x60, 0x58, 0xD5, 0xA4, 0xF0, 0x59, 0xF3, 0xAC, 0x60, 0x5A, 0xB5, 0x86, 0xF0, 0x5B, 0xD3, 0x8E, 0x60, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0xB3, 0x62, 0x50, 0x5E, 0x7E, 0x77, 0x60, 0x5F, 0x93, 0x52, 0x60, 0x60, 0x5E, 0x59, 0x60, -0x61, 0x7B, 0x1D, 0x60, 0x62, 0x3F, 0x8C, 0xE0, 0x63, 0x5A, 0xFF, 0x60, 0x64, 0x1F, 0x6E, 0xE0, -0x65, 0x3A, 0xE1, 0x60, 0x66, 0x08, 0x8B, 0x60, 0x67, 0x1A, 0xC3, 0x60, 0x67, 0xE8, 0x6D, 0x60, -0x68, 0xFA, 0xA5, 0x60, 0x69, 0xC8, 0x4F, 0x60, 0x6A, 0xDA, 0x87, 0x60, 0x6B, 0xA8, 0x31, 0x60, -0x6C, 0xC3, 0xA3, 0xE0, 0x6D, 0x88, 0x13, 0x60, 0x6E, 0xA3, 0x85, 0xE0, 0x6F, 0x67, 0xF5, 0x60, -0x70, 0x83, 0x67, 0xE0, 0x71, 0x51, 0x11, 0xE0, 0x72, 0x63, 0x49, 0xE0, 0x73, 0x30, 0xF3, 0xE0, -0x74, 0x43, 0x2B, 0xE0, 0x75, 0x10, 0xD5, 0xE0, 0x76, 0x2C, 0x48, 0x60, 0x76, 0xF0, 0xB7, 0xE0, -0x78, 0x0C, 0x2A, 0x60, 0x78, 0xD0, 0x99, 0xE0, 0x79, 0xEC, 0x0C, 0x60, 0x7A, 0xB0, 0x7B, 0xE0, -0x7B, 0xCB, 0xEE, 0x60, 0x7C, 0x99, 0x98, 0x60, 0x7D, 0xAB, 0xD0, 0x60, 0x7E, 0x79, 0x7A, 0x60, -0x7F, 0x8B, 0xB2, 0x60, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x61, 0x7B, 0x1D, 0x60, 0x62, 0x3F, 0x8C, 0xE0, 0x63, 0x5C, 0x5E, 0xF0, 0x64, 0x1E, 0x39, 0x80, +0x65, 0x3C, 0x40, 0xF0, 0x66, 0x07, 0x56, 0x00, 0x67, 0x1C, 0x22, 0xF0, 0x67, 0xE7, 0x38, 0x00, +0x68, 0xFC, 0x04, 0xF0, 0x69, 0xC7, 0x1A, 0x00, 0x6A, 0xDB, 0xE6, 0xF0, 0x6B, 0xA6, 0xFC, 0x00, +0x6C, 0xC5, 0x03, 0x70, 0x6D, 0x86, 0xDE, 0x00, 0x6E, 0xA4, 0xE5, 0x70, 0x6F, 0x66, 0xC0, 0x00, +0x70, 0x84, 0xC7, 0x70, 0x71, 0x4F, 0xDC, 0x80, 0x72, 0x64, 0xA9, 0x70, 0x73, 0x2F, 0xBE, 0x80, +0x74, 0x44, 0x8B, 0x70, 0x75, 0x0F, 0xA0, 0x80, 0x76, 0x2D, 0xA7, 0xF0, 0x76, 0xEF, 0x82, 0x80, +0x78, 0x0D, 0x89, 0xF0, 0x78, 0xCF, 0x64, 0x80, 0x79, 0xED, 0x6B, 0xF0, 0x7A, 0xAF, 0x46, 0x80, +0x7B, 0xCD, 0x4D, 0xF0, 0x7C, 0x98, 0x63, 0x00, 0x7D, 0xAD, 0x2F, 0xF0, 0x7E, 0x78, 0x45, 0x00, +0x7F, 0x8D, 0x11, 0xF0, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x06, 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x07, 0x08, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, @@ -42931,22 +42939,22 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x9D, 0x43, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xB3, 0x62, 0x50, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7E, 0x77, 0x60, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x93, 0x52, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5E, 0x59, 0x60, 0x00, 0x00, 0x00, 0x00, 0x61, 0x7B, 0x1D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x62, -0x3F, 0x8C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x5A, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x64, -0x1F, 0x6E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x3A, 0xE1, 0x60, 0x00, 0x00, 0x00, 0x00, 0x66, -0x08, 0x8B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x67, 0x1A, 0xC3, 0x60, 0x00, 0x00, 0x00, 0x00, 0x67, -0xE8, 0x6D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x68, 0xFA, 0xA5, 0x60, 0x00, 0x00, 0x00, 0x00, 0x69, -0xC8, 0x4F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xDA, 0x87, 0x60, 0x00, 0x00, 0x00, 0x00, 0x6B, -0xA8, 0x31, 0x60, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xC3, 0xA3, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x6D, -0x88, 0x13, 0x60, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xA3, 0x85, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x6F, -0x67, 0xF5, 0x60, 0x00, 0x00, 0x00, 0x00, 0x70, 0x83, 0x67, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x71, -0x51, 0x11, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x72, 0x63, 0x49, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x73, -0x30, 0xF3, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x74, 0x43, 0x2B, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x75, -0x10, 0xD5, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x2C, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x76, -0xF0, 0xB7, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x2A, 0x60, 0x00, 0x00, 0x00, 0x00, 0x78, -0xD0, 0x99, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x79, 0xEC, 0x0C, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7A, -0xB0, 0x7B, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xCB, 0xEE, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7C, -0x99, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xAB, 0xD0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7E, -0x79, 0x7A, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x8B, 0xB2, 0x60, 0x03, 0x01, 0x02, 0x01, 0x02, +0x3F, 0x8C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x5C, 0x5E, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x64, +0x1E, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x65, 0x3C, 0x40, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x66, +0x07, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x1C, 0x22, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x67, +0xE7, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xFC, 0x04, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x69, +0xC7, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xDB, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x6B, +0xA6, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xC5, 0x03, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6D, +0x86, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xA4, 0xE5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6F, +0x66, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x84, 0xC7, 0x70, 0x00, 0x00, 0x00, 0x00, 0x71, +0x4F, 0xDC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x72, 0x64, 0xA9, 0x70, 0x00, 0x00, 0x00, 0x00, 0x73, +0x2F, 0xBE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x74, 0x44, 0x8B, 0x70, 0x00, 0x00, 0x00, 0x00, 0x75, +0x0F, 0xA0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x76, 0x2D, 0xA7, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x76, +0xEF, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0D, 0x89, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x78, +0xCF, 0x64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x79, 0xED, 0x6B, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7A, +0xAF, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xCD, 0x4D, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7C, +0x98, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xAD, 0x2F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7E, +0x78, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x8D, 0x11, 0xF0, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x06, 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x07, 0x08, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, @@ -42963,8 +42971,8 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x49, 0x44, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, -0x2C, 0x4D, 0x33, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x37, 0x32, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x34, -0x2E, 0x34, 0x2F, 0x32, 0x35, 0x0A, 0x00, 0xB9, 0x64, 0xF0, 0x01, 0x47, 0x40, 0x0A, 0x00, 0x00, +0x2C, 0x4D, 0x33, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x35, 0x30, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x34, +0x2E, 0x34, 0x2F, 0x35, 0x30, 0x0A, 0x00, 0xB9, 0x64, 0xF0, 0x01, 0x47, 0x40, 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x47, 0x61, 0x7A, 0x61, 0x20, 0x53, 0x74, 0x72, 0x69, 0x70, /* Asia/Harbin */ @@ -43039,14 +43047,14 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x58, 0x13, 0xCA, 0x60, 0x58, 0xD5, 0xA4, 0xF0, 0x59, 0xF3, 0xAC, 0x60, 0x5A, 0xB5, 0x86, 0xF0, 0x5B, 0xD3, 0x8E, 0x60, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0xB3, 0x62, 0x50, 0x5E, 0x7E, 0x77, 0x60, 0x5F, 0x93, 0x52, 0x60, 0x60, 0x5E, 0x59, 0x60, 0x61, 0x7B, 0x1D, 0x60, 0x62, 0x3F, 0x8C, 0xE0, -0x63, 0x5A, 0xFF, 0x60, 0x64, 0x1F, 0x6E, 0xE0, 0x65, 0x3A, 0xE1, 0x60, 0x66, 0x08, 0x8B, 0x60, -0x67, 0x1A, 0xC3, 0x60, 0x67, 0xE8, 0x6D, 0x60, 0x68, 0xFA, 0xA5, 0x60, 0x69, 0xC8, 0x4F, 0x60, -0x6A, 0xDA, 0x87, 0x60, 0x6B, 0xA8, 0x31, 0x60, 0x6C, 0xC3, 0xA3, 0xE0, 0x6D, 0x88, 0x13, 0x60, -0x6E, 0xA3, 0x85, 0xE0, 0x6F, 0x67, 0xF5, 0x60, 0x70, 0x83, 0x67, 0xE0, 0x71, 0x51, 0x11, 0xE0, -0x72, 0x63, 0x49, 0xE0, 0x73, 0x30, 0xF3, 0xE0, 0x74, 0x43, 0x2B, 0xE0, 0x75, 0x10, 0xD5, 0xE0, -0x76, 0x2C, 0x48, 0x60, 0x76, 0xF0, 0xB7, 0xE0, 0x78, 0x0C, 0x2A, 0x60, 0x78, 0xD0, 0x99, 0xE0, -0x79, 0xEC, 0x0C, 0x60, 0x7A, 0xB0, 0x7B, 0xE0, 0x7B, 0xCB, 0xEE, 0x60, 0x7C, 0x99, 0x98, 0x60, -0x7D, 0xAB, 0xD0, 0x60, 0x7E, 0x79, 0x7A, 0x60, 0x7F, 0x8B, 0xB2, 0x60, 0x03, 0x01, 0x02, 0x01, +0x63, 0x5C, 0x5E, 0xF0, 0x64, 0x1E, 0x39, 0x80, 0x65, 0x3C, 0x40, 0xF0, 0x66, 0x07, 0x56, 0x00, +0x67, 0x1C, 0x22, 0xF0, 0x67, 0xE7, 0x38, 0x00, 0x68, 0xFC, 0x04, 0xF0, 0x69, 0xC7, 0x1A, 0x00, +0x6A, 0xDB, 0xE6, 0xF0, 0x6B, 0xA6, 0xFC, 0x00, 0x6C, 0xC5, 0x03, 0x70, 0x6D, 0x86, 0xDE, 0x00, +0x6E, 0xA4, 0xE5, 0x70, 0x6F, 0x66, 0xC0, 0x00, 0x70, 0x84, 0xC7, 0x70, 0x71, 0x4F, 0xDC, 0x80, +0x72, 0x64, 0xA9, 0x70, 0x73, 0x2F, 0xBE, 0x80, 0x74, 0x44, 0x8B, 0x70, 0x75, 0x0F, 0xA0, 0x80, +0x76, 0x2D, 0xA7, 0xF0, 0x76, 0xEF, 0x82, 0x80, 0x78, 0x0D, 0x89, 0xF0, 0x78, 0xCF, 0x64, 0x80, +0x79, 0xED, 0x6B, 0xF0, 0x7A, 0xAF, 0x46, 0x80, 0x7B, 0xCD, 0x4D, 0xF0, 0x7C, 0x98, 0x63, 0x00, +0x7D, 0xAD, 0x2F, 0xF0, 0x7E, 0x78, 0x45, 0x00, 0x7F, 0x8D, 0x11, 0xF0, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x06, 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x07, 0x08, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, @@ -43126,22 +43134,22 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x00, 0x5D, 0xB3, 0x62, 0x50, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7E, 0x77, 0x60, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x93, 0x52, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5E, 0x59, 0x60, 0x00, 0x00, 0x00, 0x00, 0x61, 0x7B, 0x1D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0x8C, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x63, 0x5A, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1F, 0x6E, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x65, 0x3A, 0xE1, 0x60, 0x00, 0x00, 0x00, 0x00, 0x66, 0x08, 0x8B, 0x60, 0x00, 0x00, 0x00, -0x00, 0x67, 0x1A, 0xC3, 0x60, 0x00, 0x00, 0x00, 0x00, 0x67, 0xE8, 0x6D, 0x60, 0x00, 0x00, 0x00, -0x00, 0x68, 0xFA, 0xA5, 0x60, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC8, 0x4F, 0x60, 0x00, 0x00, 0x00, -0x00, 0x6A, 0xDA, 0x87, 0x60, 0x00, 0x00, 0x00, 0x00, 0x6B, 0xA8, 0x31, 0x60, 0x00, 0x00, 0x00, -0x00, 0x6C, 0xC3, 0xA3, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x88, 0x13, 0x60, 0x00, 0x00, 0x00, -0x00, 0x6E, 0xA3, 0x85, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x67, 0xF5, 0x60, 0x00, 0x00, 0x00, -0x00, 0x70, 0x83, 0x67, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x71, 0x51, 0x11, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x72, 0x63, 0x49, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x73, 0x30, 0xF3, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x74, 0x43, 0x2B, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x75, 0x10, 0xD5, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x76, 0x2C, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x76, 0xF0, 0xB7, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x78, 0x0C, 0x2A, 0x60, 0x00, 0x00, 0x00, 0x00, 0x78, 0xD0, 0x99, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x79, 0xEC, 0x0C, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xB0, 0x7B, 0xE0, 0x00, 0x00, 0x00, -0x00, 0x7B, 0xCB, 0xEE, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x99, 0x98, 0x60, 0x00, 0x00, 0x00, -0x00, 0x7D, 0xAB, 0xD0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x79, 0x7A, 0x60, 0x00, 0x00, 0x00, -0x00, 0x7F, 0x8B, 0xB2, 0x60, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, +0x00, 0x63, 0x5C, 0x5E, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1E, 0x39, 0x80, 0x00, 0x00, 0x00, +0x00, 0x65, 0x3C, 0x40, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x66, 0x07, 0x56, 0x00, 0x00, 0x00, 0x00, +0x00, 0x67, 0x1C, 0x22, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x67, 0xE7, 0x38, 0x00, 0x00, 0x00, 0x00, +0x00, 0x68, 0xFC, 0x04, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC7, 0x1A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x6A, 0xDB, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x6B, 0xA6, 0xFC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x6C, 0xC5, 0x03, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x86, 0xDE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x6E, 0xA4, 0xE5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x66, 0xC0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x70, 0x84, 0xC7, 0x70, 0x00, 0x00, 0x00, 0x00, 0x71, 0x4F, 0xDC, 0x80, 0x00, 0x00, 0x00, +0x00, 0x72, 0x64, 0xA9, 0x70, 0x00, 0x00, 0x00, 0x00, 0x73, 0x2F, 0xBE, 0x80, 0x00, 0x00, 0x00, +0x00, 0x74, 0x44, 0x8B, 0x70, 0x00, 0x00, 0x00, 0x00, 0x75, 0x0F, 0xA0, 0x80, 0x00, 0x00, 0x00, +0x00, 0x76, 0x2D, 0xA7, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x76, 0xEF, 0x82, 0x80, 0x00, 0x00, 0x00, +0x00, 0x78, 0x0D, 0x89, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x78, 0xCF, 0x64, 0x80, 0x00, 0x00, 0x00, +0x00, 0x79, 0xED, 0x6B, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xAF, 0x46, 0x80, 0x00, 0x00, 0x00, +0x00, 0x7B, 0xCD, 0x4D, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x98, 0x63, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7D, 0xAD, 0x2F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x78, 0x45, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7F, 0x8D, 0x11, 0xF0, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x06, 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x07, 0x08, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, @@ -43158,8 +43166,8 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x49, 0x44, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, -0x34, 0x2E, 0x34, 0x2F, 0x37, 0x32, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x32, -0x35, 0x0A, 0x00, 0xB9, 0x71, 0xF5, 0x01, 0x48, 0x35, 0x7C, 0x00, 0x00, 0x00, 0x09, 0x57, 0x65, +0x34, 0x2E, 0x34, 0x2F, 0x35, 0x30, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x34, 0x2E, 0x34, 0x2F, 0x35, +0x30, 0x0A, 0x00, 0xB9, 0x71, 0xF5, 0x01, 0x48, 0x35, 0x7C, 0x00, 0x00, 0x00, 0x09, 0x57, 0x65, 0x73, 0x74, 0x20, 0x42, 0x61, 0x6E, 0x6B, /* Asia/Ho_Chi_Minh */ @@ -61540,137 +61548,140 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x6B, /* Europe/Uzhgorod */ -0x50, 0x48, 0x50, 0x32, 0x01, 0x55, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1E, 0x80, 0x00, 0x00, 0x00, -0xC8, 0x09, 0x71, 0x90, 0xCC, 0xE7, 0x4B, 0x10, 0xCD, 0xA9, 0x17, 0x90, 0xCE, 0xA2, 0x43, 0x10, -0xCF, 0x92, 0x34, 0x10, 0xD0, 0xA1, 0x9E, 0xE0, 0xD1, 0xE5, 0xFD, 0xF0, 0x15, 0x27, 0xA7, 0xD0, +0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x22, 0x80, 0x00, 0x00, 0x00, +0xAA, 0x19, 0xA7, 0x64, 0xB5, 0xA4, 0x19, 0x60, 0xCA, 0xCD, 0x2E, 0xD0, 0xCC, 0xE7, 0x4B, 0x10, +0xCD, 0xA9, 0x17, 0x90, 0xCE, 0xA2, 0x43, 0x10, 0xCE, 0xCD, 0xA8, 0x70, 0x15, 0x27, 0xA7, 0xD0, 0x16, 0x18, 0xDC, 0x40, 0x17, 0x08, 0xDB, 0x50, 0x17, 0xFA, 0x0F, 0xC0, 0x18, 0xEA, 0x0E, 0xD0, 0x19, 0xDB, 0x43, 0x40, 0x1A, 0xCC, 0x93, 0xD0, 0x1B, 0xBC, 0xA0, 0xF0, 0x1C, 0xAC, 0x91, 0xF0, 0x1D, 0x9C, 0x82, 0xF0, 0x1E, 0x8C, 0x73, 0xF0, 0x1F, 0x7C, 0x64, 0xF0, 0x20, 0x6C, 0x55, 0xF0, 0x21, 0x5C, 0x46, 0xF0, 0x22, 0x4C, 0x37, 0xF0, 0x23, 0x3C, 0x28, 0xF0, 0x24, 0x2C, 0x19, 0xF0, -0x25, 0x1C, 0x0A, 0xF0, 0x26, 0x8D, 0x2E, 0xF0, 0x27, 0xF5, 0x42, 0xA0, 0x29, 0xD5, 0x08, 0x80, -0x2A, 0xC4, 0xF9, 0x80, 0x2B, 0xB4, 0xEA, 0x80, 0x2C, 0xA4, 0xDB, 0x80, 0x2D, 0x94, 0xCC, 0x80, -0x2E, 0x84, 0xBD, 0x80, 0x2F, 0x74, 0xAE, 0x80, 0x30, 0x64, 0x9F, 0x80, 0x31, 0x5D, 0xCB, 0x00, -0x32, 0x72, 0xB4, 0x10, 0x33, 0x3D, 0xBB, 0x10, 0x34, 0x52, 0x96, 0x10, 0x35, 0x1D, 0x9D, 0x10, -0x36, 0x32, 0x78, 0x10, 0x36, 0xFD, 0x7F, 0x10, 0x38, 0x1B, 0x94, 0x90, 0x38, 0xDD, 0x61, 0x10, -0x39, 0xFB, 0x76, 0x90, 0x3A, 0xBD, 0x43, 0x10, 0x3B, 0xDB, 0x58, 0x90, 0x3C, 0xA6, 0x5F, 0x90, -0x3D, 0xBB, 0x3A, 0x90, 0x3E, 0x86, 0x41, 0x90, 0x3F, 0x9B, 0x1C, 0x90, 0x40, 0x66, 0x23, 0x90, -0x41, 0x84, 0x39, 0x10, 0x42, 0x46, 0x05, 0x90, 0x43, 0x64, 0x1B, 0x10, 0x44, 0x25, 0xE7, 0x90, -0x45, 0x43, 0xFD, 0x10, 0x46, 0x05, 0xC9, 0x90, 0x47, 0x23, 0xDF, 0x10, 0x47, 0xEE, 0xE6, 0x10, -0x49, 0x03, 0xC1, 0x10, 0x49, 0xCE, 0xC8, 0x10, 0x4A, 0xE3, 0xA3, 0x10, 0x4B, 0xAE, 0xAA, 0x10, -0x4C, 0xCC, 0xBF, 0x90, 0x4D, 0x8E, 0x8C, 0x10, 0x4E, 0xAC, 0xA1, 0x90, 0x4F, 0x6E, 0x6E, 0x10, -0x50, 0x8C, 0x83, 0x90, 0x51, 0x57, 0x8A, 0x90, 0x52, 0x6C, 0x65, 0x90, 0x53, 0x37, 0x6C, 0x90, -0x54, 0x4C, 0x47, 0x90, 0x55, 0x17, 0x4E, 0x90, 0x56, 0x2C, 0x29, 0x90, 0x56, 0xF7, 0x30, 0x90, -0x58, 0x15, 0x46, 0x10, 0x58, 0xD7, 0x12, 0x90, 0x59, 0xF5, 0x28, 0x10, 0x5A, 0xB6, 0xF4, 0x90, -0x5B, 0xD5, 0x0A, 0x10, 0x5C, 0xA0, 0x11, 0x10, 0x5D, 0xB4, 0xEC, 0x10, 0x5E, 0x7F, 0xF3, 0x10, -0x5F, 0x94, 0xCE, 0x10, 0x60, 0x5F, 0xD5, 0x10, 0x61, 0x7D, 0xEA, 0x90, 0x62, 0x3F, 0xB7, 0x10, -0x63, 0x5D, 0xCC, 0x90, 0x64, 0x1F, 0x99, 0x10, 0x65, 0x3D, 0xAE, 0x90, 0x66, 0x08, 0xB5, 0x90, -0x67, 0x1D, 0x90, 0x90, 0x67, 0xE8, 0x97, 0x90, 0x68, 0xFD, 0x72, 0x90, 0x69, 0xC8, 0x79, 0x90, -0x6A, 0xDD, 0x54, 0x90, 0x6B, 0xA8, 0x5B, 0x90, 0x6C, 0xC6, 0x71, 0x10, 0x6D, 0x88, 0x3D, 0x90, -0x6E, 0xA6, 0x53, 0x10, 0x6F, 0x68, 0x1F, 0x90, 0x70, 0x86, 0x35, 0x10, 0x71, 0x51, 0x3C, 0x10, -0x72, 0x66, 0x17, 0x10, 0x73, 0x31, 0x1E, 0x10, 0x74, 0x45, 0xF9, 0x10, 0x75, 0x11, 0x00, 0x10, -0x76, 0x2F, 0x15, 0x90, 0x76, 0xF0, 0xE2, 0x10, 0x78, 0x0E, 0xF7, 0x90, 0x78, 0xD0, 0xC4, 0x10, -0x79, 0xEE, 0xD9, 0x90, 0x7A, 0xB0, 0xA6, 0x10, 0x7B, 0xCE, 0xBB, 0x90, 0x7C, 0x99, 0xC2, 0x90, -0x7D, 0xAE, 0x9D, 0x90, 0x7E, 0x79, 0xA4, 0x90, 0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x03, 0x02, -0x03, 0x02, 0x01, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x06, 0x07, 0x06, 0x07, 0x06, -0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x01, 0x08, 0x09, 0x0A, 0x09, 0x0A, 0x09, 0x0A, 0x09, 0x0A, -0x09, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x00, 0x00, 0x14, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, -0x00, 0x00, 0x1C, 0x20, 0x01, 0x08, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x38, 0x40, -0x01, 0x0D, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x11, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x11, 0x00, 0x00, -0x38, 0x40, 0x01, 0x0D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x19, -0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, -0x01, 0x19, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, -0x53, 0x44, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x45, 0x45, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, -0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, -0x00, 0x0D, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0xEE, 0xB0, 0x18, 0xFF, 0xFF, -0xFF, 0xFF, 0xC8, 0x09, 0x71, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xE7, 0x4B, 0x10, 0xFF, 0xFF, -0xFF, 0xFF, 0xCD, 0xA9, 0x17, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, -0xFF, 0xFF, 0xCF, 0x92, 0x34, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xA1, 0x9E, 0xE0, 0xFF, 0xFF, -0xFF, 0xFF, 0xD1, 0xE5, 0xFD, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x27, 0xA7, 0xD0, 0x00, 0x00, -0x00, 0x00, 0x16, 0x18, 0xDC, 0x40, 0x00, 0x00, 0x00, 0x00, 0x17, 0x08, 0xDB, 0x50, 0x00, 0x00, -0x00, 0x00, 0x17, 0xFA, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x18, 0xEA, 0x0E, 0xD0, 0x00, 0x00, -0x00, 0x00, 0x19, 0xDB, 0x43, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xCC, 0x93, 0xD0, 0x00, 0x00, -0x00, 0x00, 0x1B, 0xBC, 0xA0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xAC, 0x91, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x1D, 0x9C, 0x82, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x8C, 0x73, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x1F, 0x7C, 0x64, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x6C, 0x55, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x21, 0x5C, 0x46, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x22, 0x4C, 0x37, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x23, 0x3C, 0x28, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2C, 0x19, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x25, 0x1C, 0x0A, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x26, 0x8D, 0x2E, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x27, 0xF5, 0x42, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, 0x00, -0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, 0x00, -0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, 0x00, -0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, 0x00, -0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, 0x00, -0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3D, 0xBB, 0x10, 0x00, 0x00, -0x00, 0x00, 0x34, 0x52, 0x96, 0x10, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1D, 0x9D, 0x10, 0x00, 0x00, -0x00, 0x00, 0x36, 0x32, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0xFD, 0x7F, 0x10, 0x00, 0x00, -0x00, 0x00, 0x38, 0x1B, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x38, 0xDD, 0x61, 0x10, 0x00, 0x00, -0x00, 0x00, 0x39, 0xFB, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xBD, 0x43, 0x10, 0x00, 0x00, -0x00, 0x00, 0x3B, 0xDB, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xA6, 0x5F, 0x90, 0x00, 0x00, -0x00, 0x00, 0x3D, 0xBB, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x86, 0x41, 0x90, 0x00, 0x00, -0x00, 0x00, 0x3F, 0x9B, 0x1C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x66, 0x23, 0x90, 0x00, 0x00, -0x00, 0x00, 0x41, 0x84, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x42, 0x46, 0x05, 0x90, 0x00, 0x00, -0x00, 0x00, 0x43, 0x64, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25, 0xE7, 0x90, 0x00, 0x00, -0x00, 0x00, 0x45, 0x43, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0xC9, 0x90, 0x00, 0x00, -0x00, 0x00, 0x47, 0x23, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xEE, 0xE6, 0x10, 0x00, 0x00, -0x00, 0x00, 0x49, 0x03, 0xC1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xCE, 0xC8, 0x10, 0x00, 0x00, -0x00, 0x00, 0x4A, 0xE3, 0xA3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xAE, 0xAA, 0x10, 0x00, 0x00, -0x00, 0x00, 0x4C, 0xCC, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x8E, 0x8C, 0x10, 0x00, 0x00, -0x00, 0x00, 0x4E, 0xAC, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6E, 0x10, 0x00, 0x00, -0x00, 0x00, 0x50, 0x8C, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x57, 0x8A, 0x90, 0x00, 0x00, -0x00, 0x00, 0x52, 0x6C, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x6C, 0x90, 0x00, 0x00, -0x00, 0x00, 0x54, 0x4C, 0x47, 0x90, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x4E, 0x90, 0x00, 0x00, -0x00, 0x00, 0x56, 0x2C, 0x29, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x30, 0x90, 0x00, 0x00, -0x00, 0x00, 0x58, 0x15, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x12, 0x90, 0x00, 0x00, -0x00, 0x00, 0x59, 0xF5, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB6, 0xF4, 0x90, 0x00, 0x00, -0x00, 0x00, 0x5B, 0xD5, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xA0, 0x11, 0x10, 0x00, 0x00, -0x00, 0x00, 0x5D, 0xB4, 0xEC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7F, 0xF3, 0x10, 0x00, 0x00, -0x00, 0x00, 0x5F, 0x94, 0xCE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5F, 0xD5, 0x10, 0x00, 0x00, -0x00, 0x00, 0x61, 0x7D, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xB7, 0x10, 0x00, 0x00, -0x00, 0x00, 0x63, 0x5D, 0xCC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1F, 0x99, 0x10, 0x00, 0x00, -0x00, 0x00, 0x65, 0x3D, 0xAE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x66, 0x08, 0xB5, 0x90, 0x00, 0x00, -0x00, 0x00, 0x67, 0x1D, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xE8, 0x97, 0x90, 0x00, 0x00, -0x00, 0x00, 0x68, 0xFD, 0x72, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC8, 0x79, 0x90, 0x00, 0x00, -0x00, 0x00, 0x6A, 0xDD, 0x54, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6B, 0xA8, 0x5B, 0x90, 0x00, 0x00, -0x00, 0x00, 0x6C, 0xC6, 0x71, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x88, 0x3D, 0x90, 0x00, 0x00, -0x00, 0x00, 0x6E, 0xA6, 0x53, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x68, 0x1F, 0x90, 0x00, 0x00, -0x00, 0x00, 0x70, 0x86, 0x35, 0x10, 0x00, 0x00, 0x00, 0x00, 0x71, 0x51, 0x3C, 0x10, 0x00, 0x00, -0x00, 0x00, 0x72, 0x66, 0x17, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x31, 0x1E, 0x10, 0x00, 0x00, -0x00, 0x00, 0x74, 0x45, 0xF9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, 0x10, 0x00, 0x00, -0x00, 0x00, 0x76, 0x2F, 0x15, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0xF0, 0xE2, 0x10, 0x00, 0x00, -0x00, 0x00, 0x78, 0x0E, 0xF7, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xD0, 0xC4, 0x10, 0x00, 0x00, -0x00, 0x00, 0x79, 0xEE, 0xD9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xB0, 0xA6, 0x10, 0x00, 0x00, -0x00, 0x00, 0x7B, 0xCE, 0xBB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x99, 0xC2, 0x90, 0x00, 0x00, -0x00, 0x00, 0x7D, 0xAE, 0x9D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x79, 0xA4, 0x90, 0x00, 0x00, -0x00, 0x00, 0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x05, 0x04, 0x05, -0x04, 0x05, 0x04, 0x05, 0x04, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, -0x01, 0x08, 0x09, 0x0A, 0x09, 0x0A, 0x09, 0x0A, 0x09, 0x0A, 0x09, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, -0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x00, 0x00, -0x14, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x08, -0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x38, 0x40, 0x01, 0x0D, 0x00, 0x00, 0x2A, 0x30, -0x00, 0x11, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x11, 0x00, 0x00, 0x38, 0x40, 0x01, 0x0D, 0x00, 0x00, -0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x19, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, -0x00, 0x00, 0x1C, 0x20, 0x00, 0x15, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x19, 0x4C, 0x4D, 0x54, 0x00, -0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x4D, 0x53, 0x4B, -0x00, 0x45, 0x45, 0x54, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, -0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x01, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, -0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, -0x34, 0x0A, 0x00, 0xD3, 0x83, 0x22, 0x01, 0x34, 0xAF, 0x70, 0x00, 0x00, 0x00, 0x0E, 0x54, 0x72, -0x61, 0x6E, 0x73, 0x63, 0x61, 0x72, 0x70, 0x61, 0x74, 0x68, 0x69, 0x61, +0x25, 0x1C, 0x0A, 0xF0, 0x26, 0x0B, 0xFB, 0xF0, 0x26, 0x8D, 0x20, 0xE0, 0x28, 0xE5, 0x17, 0x80, +0x29, 0xD5, 0x08, 0x80, 0x2A, 0xC4, 0xF9, 0x80, 0x2B, 0xB4, 0xEA, 0x80, 0x2C, 0xA4, 0xDB, 0x80, +0x2D, 0x94, 0xCC, 0x80, 0x2E, 0x84, 0xBD, 0x80, 0x2F, 0x74, 0xAE, 0x80, 0x30, 0x64, 0x9F, 0x80, +0x31, 0x5D, 0xCB, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x33, 0x3D, 0xBB, 0x10, 0x34, 0x52, 0x96, 0x10, +0x35, 0x1D, 0x9D, 0x10, 0x36, 0x32, 0x78, 0x10, 0x36, 0xFD, 0x7F, 0x10, 0x38, 0x1B, 0x94, 0x90, +0x38, 0xDD, 0x61, 0x10, 0x39, 0xFB, 0x76, 0x90, 0x3A, 0xBD, 0x43, 0x10, 0x3B, 0xDB, 0x58, 0x90, +0x3C, 0xA6, 0x5F, 0x90, 0x3D, 0xBB, 0x3A, 0x90, 0x3E, 0x86, 0x41, 0x90, 0x3F, 0x9B, 0x1C, 0x90, +0x40, 0x66, 0x23, 0x90, 0x41, 0x84, 0x39, 0x10, 0x42, 0x46, 0x05, 0x90, 0x43, 0x64, 0x1B, 0x10, +0x44, 0x25, 0xE7, 0x90, 0x45, 0x43, 0xFD, 0x10, 0x46, 0x05, 0xC9, 0x90, 0x47, 0x23, 0xDF, 0x10, +0x47, 0xEE, 0xE6, 0x10, 0x49, 0x03, 0xC1, 0x10, 0x49, 0xCE, 0xC8, 0x10, 0x4A, 0xE3, 0xA3, 0x10, +0x4B, 0xAE, 0xAA, 0x10, 0x4C, 0xCC, 0xBF, 0x90, 0x4D, 0x8E, 0x8C, 0x10, 0x4E, 0xAC, 0xA1, 0x90, +0x4F, 0x6E, 0x6E, 0x10, 0x50, 0x8C, 0x83, 0x90, 0x51, 0x57, 0x8A, 0x90, 0x52, 0x6C, 0x65, 0x90, +0x53, 0x37, 0x6C, 0x90, 0x54, 0x4C, 0x47, 0x90, 0x55, 0x17, 0x4E, 0x90, 0x56, 0x2C, 0x29, 0x90, +0x56, 0xF7, 0x30, 0x90, 0x58, 0x15, 0x46, 0x10, 0x58, 0xD7, 0x12, 0x90, 0x59, 0xF5, 0x28, 0x10, +0x5A, 0xB6, 0xF4, 0x90, 0x5B, 0xD5, 0x0A, 0x10, 0x5C, 0xA0, 0x11, 0x10, 0x5D, 0xB4, 0xEC, 0x10, +0x5E, 0x7F, 0xF3, 0x10, 0x5F, 0x94, 0xCE, 0x10, 0x60, 0x5F, 0xD5, 0x10, 0x61, 0x7D, 0xEA, 0x90, +0x62, 0x3F, 0xB7, 0x10, 0x63, 0x5D, 0xCC, 0x90, 0x64, 0x1F, 0x99, 0x10, 0x65, 0x3D, 0xAE, 0x90, +0x66, 0x08, 0xB5, 0x90, 0x67, 0x1D, 0x90, 0x90, 0x67, 0xE8, 0x97, 0x90, 0x68, 0xFD, 0x72, 0x90, +0x69, 0xC8, 0x79, 0x90, 0x6A, 0xDD, 0x54, 0x90, 0x6B, 0xA8, 0x5B, 0x90, 0x6C, 0xC6, 0x71, 0x10, +0x6D, 0x88, 0x3D, 0x90, 0x6E, 0xA6, 0x53, 0x10, 0x6F, 0x68, 0x1F, 0x90, 0x70, 0x86, 0x35, 0x10, +0x71, 0x51, 0x3C, 0x10, 0x72, 0x66, 0x17, 0x10, 0x73, 0x31, 0x1E, 0x10, 0x74, 0x45, 0xF9, 0x10, +0x75, 0x11, 0x00, 0x10, 0x76, 0x2F, 0x15, 0x90, 0x76, 0xF0, 0xE2, 0x10, 0x78, 0x0E, 0xF7, 0x90, +0x78, 0xD0, 0xC4, 0x10, 0x79, 0xEE, 0xD9, 0x90, 0x7A, 0xB0, 0xA6, 0x10, 0x7B, 0xCE, 0xBB, 0x90, +0x7C, 0x99, 0xC2, 0x90, 0x7D, 0xAE, 0x9D, 0x90, 0x7E, 0x79, 0xA4, 0x90, 0x7F, 0x8E, 0x7F, 0x90, +0x01, 0x02, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x07, 0x03, 0x07, 0x03, 0x07, 0x03, 0x07, 0x08, +0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0B, 0x0C, +0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x00, 0x00, 0x1C, 0x9C, 0x00, 0x00, 0x00, +0x00, 0x1C, 0x9C, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, +0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x14, 0x00, 0x00, 0x1C, +0x20, 0x01, 0x14, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, +0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, +0x08, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, +0x30, 0x01, 0x1D, 0x4C, 0x4D, 0x54, 0x00, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, +0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, +0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, +0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x22, 0xFF, +0xFF, 0xFF, 0xFF, 0x56, 0xB6, 0xC7, 0x64, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x19, 0xA7, 0x64, 0xFF, +0xFF, 0xFF, 0xFF, 0xB5, 0xA4, 0x19, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCD, 0x2E, 0xD0, 0xFF, +0xFF, 0xFF, 0xFF, 0xCC, 0xE7, 0x4B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xA9, 0x17, 0x90, 0xFF, +0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xCD, 0xA8, 0x70, 0x00, +0x00, 0x00, 0x00, 0x15, 0x27, 0xA7, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0xDC, 0x40, 0x00, +0x00, 0x00, 0x00, 0x17, 0x08, 0xDB, 0x50, 0x00, 0x00, 0x00, 0x00, 0x17, 0xFA, 0x0F, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x18, 0xEA, 0x0E, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x19, 0xDB, 0x43, 0x40, 0x00, +0x00, 0x00, 0x00, 0x1A, 0xCC, 0x93, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xBC, 0xA0, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x1C, 0xAC, 0x91, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x9C, 0x82, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x1E, 0x8C, 0x73, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x7C, 0x64, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x20, 0x6C, 0x55, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x5C, 0x46, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x22, 0x4C, 0x37, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x23, 0x3C, 0x28, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x24, 0x2C, 0x19, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x25, 0x1C, 0x0A, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x26, 0x0B, 0xFB, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x26, 0x8D, 0x20, 0xE0, 0x00, +0x00, 0x00, 0x00, 0x28, 0xE5, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, +0x00, 0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, +0x00, 0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3D, 0xBB, 0x10, 0x00, +0x00, 0x00, 0x00, 0x34, 0x52, 0x96, 0x10, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1D, 0x9D, 0x10, 0x00, +0x00, 0x00, 0x00, 0x36, 0x32, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0xFD, 0x7F, 0x10, 0x00, +0x00, 0x00, 0x00, 0x38, 0x1B, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x38, 0xDD, 0x61, 0x10, 0x00, +0x00, 0x00, 0x00, 0x39, 0xFB, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xBD, 0x43, 0x10, 0x00, +0x00, 0x00, 0x00, 0x3B, 0xDB, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xA6, 0x5F, 0x90, 0x00, +0x00, 0x00, 0x00, 0x3D, 0xBB, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x86, 0x41, 0x90, 0x00, +0x00, 0x00, 0x00, 0x3F, 0x9B, 0x1C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x66, 0x23, 0x90, 0x00, +0x00, 0x00, 0x00, 0x41, 0x84, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x42, 0x46, 0x05, 0x90, 0x00, +0x00, 0x00, 0x00, 0x43, 0x64, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25, 0xE7, 0x90, 0x00, +0x00, 0x00, 0x00, 0x45, 0x43, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0xC9, 0x90, 0x00, +0x00, 0x00, 0x00, 0x47, 0x23, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xEE, 0xE6, 0x10, 0x00, +0x00, 0x00, 0x00, 0x49, 0x03, 0xC1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xCE, 0xC8, 0x10, 0x00, +0x00, 0x00, 0x00, 0x4A, 0xE3, 0xA3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xAE, 0xAA, 0x10, 0x00, +0x00, 0x00, 0x00, 0x4C, 0xCC, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x8E, 0x8C, 0x10, 0x00, +0x00, 0x00, 0x00, 0x4E, 0xAC, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6E, 0x10, 0x00, +0x00, 0x00, 0x00, 0x50, 0x8C, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x57, 0x8A, 0x90, 0x00, +0x00, 0x00, 0x00, 0x52, 0x6C, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x6C, 0x90, 0x00, +0x00, 0x00, 0x00, 0x54, 0x4C, 0x47, 0x90, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x4E, 0x90, 0x00, +0x00, 0x00, 0x00, 0x56, 0x2C, 0x29, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x30, 0x90, 0x00, +0x00, 0x00, 0x00, 0x58, 0x15, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x12, 0x90, 0x00, +0x00, 0x00, 0x00, 0x59, 0xF5, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB6, 0xF4, 0x90, 0x00, +0x00, 0x00, 0x00, 0x5B, 0xD5, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xA0, 0x11, 0x10, 0x00, +0x00, 0x00, 0x00, 0x5D, 0xB4, 0xEC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7F, 0xF3, 0x10, 0x00, +0x00, 0x00, 0x00, 0x5F, 0x94, 0xCE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5F, 0xD5, 0x10, 0x00, +0x00, 0x00, 0x00, 0x61, 0x7D, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xB7, 0x10, 0x00, +0x00, 0x00, 0x00, 0x63, 0x5D, 0xCC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1F, 0x99, 0x10, 0x00, +0x00, 0x00, 0x00, 0x65, 0x3D, 0xAE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x66, 0x08, 0xB5, 0x90, 0x00, +0x00, 0x00, 0x00, 0x67, 0x1D, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xE8, 0x97, 0x90, 0x00, +0x00, 0x00, 0x00, 0x68, 0xFD, 0x72, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC8, 0x79, 0x90, 0x00, +0x00, 0x00, 0x00, 0x6A, 0xDD, 0x54, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6B, 0xA8, 0x5B, 0x90, 0x00, +0x00, 0x00, 0x00, 0x6C, 0xC6, 0x71, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x88, 0x3D, 0x90, 0x00, +0x00, 0x00, 0x00, 0x6E, 0xA6, 0x53, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x68, 0x1F, 0x90, 0x00, +0x00, 0x00, 0x00, 0x70, 0x86, 0x35, 0x10, 0x00, 0x00, 0x00, 0x00, 0x71, 0x51, 0x3C, 0x10, 0x00, +0x00, 0x00, 0x00, 0x72, 0x66, 0x17, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x31, 0x1E, 0x10, 0x00, +0x00, 0x00, 0x00, 0x74, 0x45, 0xF9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, 0x10, 0x00, +0x00, 0x00, 0x00, 0x76, 0x2F, 0x15, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0xF0, 0xE2, 0x10, 0x00, +0x00, 0x00, 0x00, 0x78, 0x0E, 0xF7, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xD0, 0xC4, 0x10, 0x00, +0x00, 0x00, 0x00, 0x79, 0xEE, 0xD9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xB0, 0xA6, 0x10, 0x00, +0x00, 0x00, 0x00, 0x7B, 0xCE, 0xBB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x99, 0xC2, 0x90, 0x00, +0x00, 0x00, 0x00, 0x7D, 0xAE, 0x9D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x79, 0xA4, 0x90, 0x00, +0x00, 0x00, 0x00, 0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x07, +0x03, 0x07, 0x03, 0x07, 0x03, 0x07, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, +0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0D, 0x0E, 0x0D, +0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x00, 0x00, 0x1C, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x9C, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, +0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x10, 0x00, 0x00, +0x1C, 0x20, 0x01, 0x14, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x14, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, +0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, +0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, +0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x4C, 0x4D, 0x54, 0x00, 0x4B, 0x4D, +0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, +0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, +0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, +0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, /* Europe/Vaduz */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x4C, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -62610,143 +62621,140 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { 0x00, 0xCF, 0x36, 0xE0, 0x01, 0x2B, 0x05, 0x7A, 0x00, 0x00, 0x00, 0x00, /* Europe/Zaporozhye */ -0x50, 0x48, 0x50, 0x32, 0x01, 0x55, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x24, 0x80, 0x00, 0x00, 0x00, -0xAA, 0x19, 0xA3, 0x30, 0xB5, 0xA4, 0x19, 0x60, 0xCA, 0xAA, 0xE7, 0xD0, 0xCC, 0xE7, 0x4B, 0x10, -0xCD, 0xA9, 0x17, 0x90, 0xCE, 0xA2, 0x43, 0x10, 0xCE, 0xBD, 0xD6, 0x70, 0x15, 0x27, 0xA7, 0xD0, +0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x22, 0x80, 0x00, 0x00, 0x00, +0xAA, 0x19, 0xA7, 0x64, 0xB5, 0xA4, 0x19, 0x60, 0xCA, 0xCD, 0x2E, 0xD0, 0xCC, 0xE7, 0x4B, 0x10, +0xCD, 0xA9, 0x17, 0x90, 0xCE, 0xA2, 0x43, 0x10, 0xCE, 0xCD, 0xA8, 0x70, 0x15, 0x27, 0xA7, 0xD0, 0x16, 0x18, 0xDC, 0x40, 0x17, 0x08, 0xDB, 0x50, 0x17, 0xFA, 0x0F, 0xC0, 0x18, 0xEA, 0x0E, 0xD0, 0x19, 0xDB, 0x43, 0x40, 0x1A, 0xCC, 0x93, 0xD0, 0x1B, 0xBC, 0xA0, 0xF0, 0x1C, 0xAC, 0x91, 0xF0, 0x1D, 0x9C, 0x82, 0xF0, 0x1E, 0x8C, 0x73, 0xF0, 0x1F, 0x7C, 0x64, 0xF0, 0x20, 0x6C, 0x55, 0xF0, 0x21, 0x5C, 0x46, 0xF0, 0x22, 0x4C, 0x37, 0xF0, 0x23, 0x3C, 0x28, 0xF0, 0x24, 0x2C, 0x19, 0xF0, -0x25, 0x1C, 0x0A, 0xF0, 0x26, 0x0B, 0xFB, 0xF0, 0x27, 0x05, 0x27, 0x70, 0x27, 0xF5, 0x18, 0x70, -0x28, 0xE4, 0xED, 0x50, 0x29, 0xD5, 0x08, 0x80, 0x2A, 0xC4, 0xF9, 0x80, 0x2B, 0xB4, 0xEA, 0x80, -0x2C, 0xA4, 0xDB, 0x80, 0x2D, 0x94, 0xCC, 0x80, 0x2E, 0x84, 0xBD, 0x80, 0x2F, 0x74, 0xAE, 0x80, -0x30, 0x64, 0x9F, 0x80, 0x31, 0x5D, 0xCB, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x33, 0x3D, 0xBB, 0x10, -0x34, 0x52, 0x96, 0x10, 0x35, 0x1D, 0x9D, 0x10, 0x36, 0x32, 0x78, 0x10, 0x36, 0xFD, 0x7F, 0x10, -0x38, 0x1B, 0x94, 0x90, 0x38, 0xDD, 0x61, 0x10, 0x39, 0xFB, 0x76, 0x90, 0x3A, 0xBD, 0x43, 0x10, -0x3B, 0xDB, 0x58, 0x90, 0x3C, 0xA6, 0x5F, 0x90, 0x3D, 0xBB, 0x3A, 0x90, 0x3E, 0x86, 0x41, 0x90, -0x3F, 0x9B, 0x1C, 0x90, 0x40, 0x66, 0x23, 0x90, 0x41, 0x84, 0x39, 0x10, 0x42, 0x46, 0x05, 0x90, -0x43, 0x64, 0x1B, 0x10, 0x44, 0x25, 0xE7, 0x90, 0x45, 0x43, 0xFD, 0x10, 0x46, 0x05, 0xC9, 0x90, -0x47, 0x23, 0xDF, 0x10, 0x47, 0xEE, 0xE6, 0x10, 0x49, 0x03, 0xC1, 0x10, 0x49, 0xCE, 0xC8, 0x10, -0x4A, 0xE3, 0xA3, 0x10, 0x4B, 0xAE, 0xAA, 0x10, 0x4C, 0xCC, 0xBF, 0x90, 0x4D, 0x8E, 0x8C, 0x10, -0x4E, 0xAC, 0xA1, 0x90, 0x4F, 0x6E, 0x6E, 0x10, 0x50, 0x8C, 0x83, 0x90, 0x51, 0x57, 0x8A, 0x90, -0x52, 0x6C, 0x65, 0x90, 0x53, 0x37, 0x6C, 0x90, 0x54, 0x4C, 0x47, 0x90, 0x55, 0x17, 0x4E, 0x90, -0x56, 0x2C, 0x29, 0x90, 0x56, 0xF7, 0x30, 0x90, 0x58, 0x15, 0x46, 0x10, 0x58, 0xD7, 0x12, 0x90, -0x59, 0xF5, 0x28, 0x10, 0x5A, 0xB6, 0xF4, 0x90, 0x5B, 0xD5, 0x0A, 0x10, 0x5C, 0xA0, 0x11, 0x10, -0x5D, 0xB4, 0xEC, 0x10, 0x5E, 0x7F, 0xF3, 0x10, 0x5F, 0x94, 0xCE, 0x10, 0x60, 0x5F, 0xD5, 0x10, -0x61, 0x7D, 0xEA, 0x90, 0x62, 0x3F, 0xB7, 0x10, 0x63, 0x5D, 0xCC, 0x90, 0x64, 0x1F, 0x99, 0x10, -0x65, 0x3D, 0xAE, 0x90, 0x66, 0x08, 0xB5, 0x90, 0x67, 0x1D, 0x90, 0x90, 0x67, 0xE8, 0x97, 0x90, -0x68, 0xFD, 0x72, 0x90, 0x69, 0xC8, 0x79, 0x90, 0x6A, 0xDD, 0x54, 0x90, 0x6B, 0xA8, 0x5B, 0x90, -0x6C, 0xC6, 0x71, 0x10, 0x6D, 0x88, 0x3D, 0x90, 0x6E, 0xA6, 0x53, 0x10, 0x6F, 0x68, 0x1F, 0x90, -0x70, 0x86, 0x35, 0x10, 0x71, 0x51, 0x3C, 0x10, 0x72, 0x66, 0x17, 0x10, 0x73, 0x31, 0x1E, 0x10, -0x74, 0x45, 0xF9, 0x10, 0x75, 0x11, 0x00, 0x10, 0x76, 0x2F, 0x15, 0x90, 0x76, 0xF0, 0xE2, 0x10, -0x78, 0x0E, 0xF7, 0x90, 0x78, 0xD0, 0xC4, 0x10, 0x79, 0xEE, 0xD9, 0x90, 0x7A, 0xB0, 0xA6, 0x10, -0x7B, 0xCE, 0xBB, 0x90, 0x7C, 0x99, 0xC2, 0x90, 0x7D, 0xAE, 0x9D, 0x90, 0x7E, 0x79, 0xA4, 0x90, -0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x07, 0x03, 0x07, 0x03, -0x07, 0x03, 0x07, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, -0x0A, 0x02, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x25, 0x1C, 0x0A, 0xF0, 0x26, 0x0B, 0xFB, 0xF0, 0x26, 0x8D, 0x20, 0xE0, 0x28, 0xE5, 0x17, 0x80, +0x29, 0xD5, 0x08, 0x80, 0x2A, 0xC4, 0xF9, 0x80, 0x2B, 0xB4, 0xEA, 0x80, 0x2C, 0xA4, 0xDB, 0x80, +0x2D, 0x94, 0xCC, 0x80, 0x2E, 0x84, 0xBD, 0x80, 0x2F, 0x74, 0xAE, 0x80, 0x30, 0x64, 0x9F, 0x80, +0x31, 0x5D, 0xCB, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x33, 0x3D, 0xBB, 0x10, 0x34, 0x52, 0x96, 0x10, +0x35, 0x1D, 0x9D, 0x10, 0x36, 0x32, 0x78, 0x10, 0x36, 0xFD, 0x7F, 0x10, 0x38, 0x1B, 0x94, 0x90, +0x38, 0xDD, 0x61, 0x10, 0x39, 0xFB, 0x76, 0x90, 0x3A, 0xBD, 0x43, 0x10, 0x3B, 0xDB, 0x58, 0x90, +0x3C, 0xA6, 0x5F, 0x90, 0x3D, 0xBB, 0x3A, 0x90, 0x3E, 0x86, 0x41, 0x90, 0x3F, 0x9B, 0x1C, 0x90, +0x40, 0x66, 0x23, 0x90, 0x41, 0x84, 0x39, 0x10, 0x42, 0x46, 0x05, 0x90, 0x43, 0x64, 0x1B, 0x10, +0x44, 0x25, 0xE7, 0x90, 0x45, 0x43, 0xFD, 0x10, 0x46, 0x05, 0xC9, 0x90, 0x47, 0x23, 0xDF, 0x10, +0x47, 0xEE, 0xE6, 0x10, 0x49, 0x03, 0xC1, 0x10, 0x49, 0xCE, 0xC8, 0x10, 0x4A, 0xE3, 0xA3, 0x10, +0x4B, 0xAE, 0xAA, 0x10, 0x4C, 0xCC, 0xBF, 0x90, 0x4D, 0x8E, 0x8C, 0x10, 0x4E, 0xAC, 0xA1, 0x90, +0x4F, 0x6E, 0x6E, 0x10, 0x50, 0x8C, 0x83, 0x90, 0x51, 0x57, 0x8A, 0x90, 0x52, 0x6C, 0x65, 0x90, +0x53, 0x37, 0x6C, 0x90, 0x54, 0x4C, 0x47, 0x90, 0x55, 0x17, 0x4E, 0x90, 0x56, 0x2C, 0x29, 0x90, +0x56, 0xF7, 0x30, 0x90, 0x58, 0x15, 0x46, 0x10, 0x58, 0xD7, 0x12, 0x90, 0x59, 0xF5, 0x28, 0x10, +0x5A, 0xB6, 0xF4, 0x90, 0x5B, 0xD5, 0x0A, 0x10, 0x5C, 0xA0, 0x11, 0x10, 0x5D, 0xB4, 0xEC, 0x10, +0x5E, 0x7F, 0xF3, 0x10, 0x5F, 0x94, 0xCE, 0x10, 0x60, 0x5F, 0xD5, 0x10, 0x61, 0x7D, 0xEA, 0x90, +0x62, 0x3F, 0xB7, 0x10, 0x63, 0x5D, 0xCC, 0x90, 0x64, 0x1F, 0x99, 0x10, 0x65, 0x3D, 0xAE, 0x90, +0x66, 0x08, 0xB5, 0x90, 0x67, 0x1D, 0x90, 0x90, 0x67, 0xE8, 0x97, 0x90, 0x68, 0xFD, 0x72, 0x90, +0x69, 0xC8, 0x79, 0x90, 0x6A, 0xDD, 0x54, 0x90, 0x6B, 0xA8, 0x5B, 0x90, 0x6C, 0xC6, 0x71, 0x10, +0x6D, 0x88, 0x3D, 0x90, 0x6E, 0xA6, 0x53, 0x10, 0x6F, 0x68, 0x1F, 0x90, 0x70, 0x86, 0x35, 0x10, +0x71, 0x51, 0x3C, 0x10, 0x72, 0x66, 0x17, 0x10, 0x73, 0x31, 0x1E, 0x10, 0x74, 0x45, 0xF9, 0x10, +0x75, 0x11, 0x00, 0x10, 0x76, 0x2F, 0x15, 0x90, 0x76, 0xF0, 0xE2, 0x10, 0x78, 0x0E, 0xF7, 0x90, +0x78, 0xD0, 0xC4, 0x10, 0x79, 0xEE, 0xD9, 0x90, 0x7A, 0xB0, 0xA6, 0x10, 0x7B, 0xCE, 0xBB, 0x90, +0x7C, 0x99, 0xC2, 0x90, 0x7D, 0xAE, 0x9D, 0x90, 0x7E, 0x79, 0xA4, 0x90, 0x7F, 0x8E, 0x7F, 0x90, +0x01, 0x02, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x07, 0x03, 0x07, 0x03, 0x07, 0x03, 0x07, 0x08, +0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0B, 0x0C, +0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, +0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x00, 0x00, 0x1C, 0x9C, 0x00, 0x00, 0x00, +0x00, 0x1C, 0x9C, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, +0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x14, 0x00, 0x00, 0x1C, +0x20, 0x01, 0x14, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, +0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, +0x08, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, +0x30, 0x01, 0x1D, 0x4C, 0x4D, 0x54, 0x00, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, +0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, +0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, +0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x22, 0xFF, +0xFF, 0xFF, 0xFF, 0x56, 0xB6, 0xC7, 0x64, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x19, 0xA7, 0x64, 0xFF, +0xFF, 0xFF, 0xFF, 0xB5, 0xA4, 0x19, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCD, 0x2E, 0xD0, 0xFF, +0xFF, 0xFF, 0xFF, 0xCC, 0xE7, 0x4B, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0xA9, 0x17, 0x90, 0xFF, +0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xCD, 0xA8, 0x70, 0x00, +0x00, 0x00, 0x00, 0x15, 0x27, 0xA7, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0xDC, 0x40, 0x00, +0x00, 0x00, 0x00, 0x17, 0x08, 0xDB, 0x50, 0x00, 0x00, 0x00, 0x00, 0x17, 0xFA, 0x0F, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x18, 0xEA, 0x0E, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x19, 0xDB, 0x43, 0x40, 0x00, +0x00, 0x00, 0x00, 0x1A, 0xCC, 0x93, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xBC, 0xA0, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x1C, 0xAC, 0x91, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x9C, 0x82, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x1E, 0x8C, 0x73, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x7C, 0x64, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x20, 0x6C, 0x55, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x5C, 0x46, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x22, 0x4C, 0x37, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x23, 0x3C, 0x28, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x24, 0x2C, 0x19, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x25, 0x1C, 0x0A, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x26, 0x0B, 0xFB, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x26, 0x8D, 0x20, 0xE0, 0x00, +0x00, 0x00, 0x00, 0x28, 0xE5, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, +0x00, 0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, +0x00, 0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, +0x00, 0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3D, 0xBB, 0x10, 0x00, +0x00, 0x00, 0x00, 0x34, 0x52, 0x96, 0x10, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1D, 0x9D, 0x10, 0x00, +0x00, 0x00, 0x00, 0x36, 0x32, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0xFD, 0x7F, 0x10, 0x00, +0x00, 0x00, 0x00, 0x38, 0x1B, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x38, 0xDD, 0x61, 0x10, 0x00, +0x00, 0x00, 0x00, 0x39, 0xFB, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xBD, 0x43, 0x10, 0x00, +0x00, 0x00, 0x00, 0x3B, 0xDB, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xA6, 0x5F, 0x90, 0x00, +0x00, 0x00, 0x00, 0x3D, 0xBB, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x86, 0x41, 0x90, 0x00, +0x00, 0x00, 0x00, 0x3F, 0x9B, 0x1C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x66, 0x23, 0x90, 0x00, +0x00, 0x00, 0x00, 0x41, 0x84, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x42, 0x46, 0x05, 0x90, 0x00, +0x00, 0x00, 0x00, 0x43, 0x64, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25, 0xE7, 0x90, 0x00, +0x00, 0x00, 0x00, 0x45, 0x43, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0xC9, 0x90, 0x00, +0x00, 0x00, 0x00, 0x47, 0x23, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xEE, 0xE6, 0x10, 0x00, +0x00, 0x00, 0x00, 0x49, 0x03, 0xC1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xCE, 0xC8, 0x10, 0x00, +0x00, 0x00, 0x00, 0x4A, 0xE3, 0xA3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xAE, 0xAA, 0x10, 0x00, +0x00, 0x00, 0x00, 0x4C, 0xCC, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x8E, 0x8C, 0x10, 0x00, +0x00, 0x00, 0x00, 0x4E, 0xAC, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6E, 0x10, 0x00, +0x00, 0x00, 0x00, 0x50, 0x8C, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x57, 0x8A, 0x90, 0x00, +0x00, 0x00, 0x00, 0x52, 0x6C, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x6C, 0x90, 0x00, +0x00, 0x00, 0x00, 0x54, 0x4C, 0x47, 0x90, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x4E, 0x90, 0x00, +0x00, 0x00, 0x00, 0x56, 0x2C, 0x29, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x30, 0x90, 0x00, +0x00, 0x00, 0x00, 0x58, 0x15, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x12, 0x90, 0x00, +0x00, 0x00, 0x00, 0x59, 0xF5, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB6, 0xF4, 0x90, 0x00, +0x00, 0x00, 0x00, 0x5B, 0xD5, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xA0, 0x11, 0x10, 0x00, +0x00, 0x00, 0x00, 0x5D, 0xB4, 0xEC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7F, 0xF3, 0x10, 0x00, +0x00, 0x00, 0x00, 0x5F, 0x94, 0xCE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5F, 0xD5, 0x10, 0x00, +0x00, 0x00, 0x00, 0x61, 0x7D, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xB7, 0x10, 0x00, +0x00, 0x00, 0x00, 0x63, 0x5D, 0xCC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1F, 0x99, 0x10, 0x00, +0x00, 0x00, 0x00, 0x65, 0x3D, 0xAE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x66, 0x08, 0xB5, 0x90, 0x00, +0x00, 0x00, 0x00, 0x67, 0x1D, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xE8, 0x97, 0x90, 0x00, +0x00, 0x00, 0x00, 0x68, 0xFD, 0x72, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC8, 0x79, 0x90, 0x00, +0x00, 0x00, 0x00, 0x6A, 0xDD, 0x54, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6B, 0xA8, 0x5B, 0x90, 0x00, +0x00, 0x00, 0x00, 0x6C, 0xC6, 0x71, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x88, 0x3D, 0x90, 0x00, +0x00, 0x00, 0x00, 0x6E, 0xA6, 0x53, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x68, 0x1F, 0x90, 0x00, +0x00, 0x00, 0x00, 0x70, 0x86, 0x35, 0x10, 0x00, 0x00, 0x00, 0x00, 0x71, 0x51, 0x3C, 0x10, 0x00, +0x00, 0x00, 0x00, 0x72, 0x66, 0x17, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x31, 0x1E, 0x10, 0x00, +0x00, 0x00, 0x00, 0x74, 0x45, 0xF9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, 0x10, 0x00, +0x00, 0x00, 0x00, 0x76, 0x2F, 0x15, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0xF0, 0xE2, 0x10, 0x00, +0x00, 0x00, 0x00, 0x78, 0x0E, 0xF7, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xD0, 0xC4, 0x10, 0x00, +0x00, 0x00, 0x00, 0x79, 0xEE, 0xD9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xB0, 0xA6, 0x10, 0x00, +0x00, 0x00, 0x00, 0x7B, 0xCE, 0xBB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x99, 0xC2, 0x90, 0x00, +0x00, 0x00, 0x00, 0x7D, 0xAE, 0x9D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x79, 0xA4, 0x90, 0x00, +0x00, 0x00, 0x00, 0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x07, +0x03, 0x07, 0x03, 0x07, 0x03, 0x07, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, +0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, -0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x00, 0x00, -0x20, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x20, 0xD0, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0A, -0x00, 0x00, 0x2A, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x12, 0x00, 0x00, 0x1C, 0x20, -0x01, 0x16, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x16, 0x00, 0x00, 0x38, 0x40, 0x01, 0x1B, 0x00, 0x00, -0x2A, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x40, 0x01, 0x1B, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1F, -0x00, 0x00, 0x2A, 0x30, 0x01, 0x1F, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0A, 0x00, 0x00, 0x1C, 0x20, -0x00, 0x0A, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1F, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x32, 0x32, -0x30, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, +0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, +0x00, 0x00, 0x1C, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x9C, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, +0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x10, 0x00, 0x00, +0x1C, 0x20, 0x01, 0x14, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x14, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, +0x00, 0x00, 0x2A, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x38, 0x40, 0x01, 0x19, 0x00, 0x00, 0x2A, 0x30, +0x01, 0x1D, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x00, 0x00, +0x1C, 0x20, 0x00, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1D, 0x4C, 0x4D, 0x54, 0x00, 0x4B, 0x4D, +0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, -0x00, 0x0F, 0x00, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0x56, 0xB6, 0xC3, 0x08, 0xFF, 0xFF, -0xFF, 0xFF, 0xAA, 0x19, 0xA3, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0xA4, 0x19, 0x60, 0xFF, 0xFF, -0xFF, 0xFF, 0xCA, 0xAA, 0xE7, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xE7, 0x4B, 0x10, 0xFF, 0xFF, -0xFF, 0xFF, 0xCD, 0xA9, 0x17, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xA2, 0x43, 0x10, 0xFF, 0xFF, -0xFF, 0xFF, 0xCE, 0xBD, 0xD6, 0x70, 0x00, 0x00, 0x00, 0x00, 0x15, 0x27, 0xA7, 0xD0, 0x00, 0x00, -0x00, 0x00, 0x16, 0x18, 0xDC, 0x40, 0x00, 0x00, 0x00, 0x00, 0x17, 0x08, 0xDB, 0x50, 0x00, 0x00, -0x00, 0x00, 0x17, 0xFA, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x18, 0xEA, 0x0E, 0xD0, 0x00, 0x00, -0x00, 0x00, 0x19, 0xDB, 0x43, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xCC, 0x93, 0xD0, 0x00, 0x00, -0x00, 0x00, 0x1B, 0xBC, 0xA0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xAC, 0x91, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x1D, 0x9C, 0x82, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x8C, 0x73, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x1F, 0x7C, 0x64, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x6C, 0x55, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x21, 0x5C, 0x46, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x22, 0x4C, 0x37, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x23, 0x3C, 0x28, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2C, 0x19, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x25, 0x1C, 0x0A, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x26, 0x0B, 0xFB, 0xF0, 0x00, 0x00, -0x00, 0x00, 0x27, 0x05, 0x27, 0x70, 0x00, 0x00, 0x00, 0x00, 0x27, 0xF5, 0x18, 0x70, 0x00, 0x00, -0x00, 0x00, 0x28, 0xE4, 0xED, 0x50, 0x00, 0x00, 0x00, 0x00, 0x29, 0xD5, 0x08, 0x80, 0x00, 0x00, -0x00, 0x00, 0x2A, 0xC4, 0xF9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xB4, 0xEA, 0x80, 0x00, 0x00, -0x00, 0x00, 0x2C, 0xA4, 0xDB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x94, 0xCC, 0x80, 0x00, 0x00, -0x00, 0x00, 0x2E, 0x84, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x74, 0xAE, 0x80, 0x00, 0x00, -0x00, 0x00, 0x30, 0x64, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5D, 0xCB, 0x00, 0x00, 0x00, -0x00, 0x00, 0x32, 0x72, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3D, 0xBB, 0x10, 0x00, 0x00, -0x00, 0x00, 0x34, 0x52, 0x96, 0x10, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1D, 0x9D, 0x10, 0x00, 0x00, -0x00, 0x00, 0x36, 0x32, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0xFD, 0x7F, 0x10, 0x00, 0x00, -0x00, 0x00, 0x38, 0x1B, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x38, 0xDD, 0x61, 0x10, 0x00, 0x00, -0x00, 0x00, 0x39, 0xFB, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xBD, 0x43, 0x10, 0x00, 0x00, -0x00, 0x00, 0x3B, 0xDB, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xA6, 0x5F, 0x90, 0x00, 0x00, -0x00, 0x00, 0x3D, 0xBB, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x86, 0x41, 0x90, 0x00, 0x00, -0x00, 0x00, 0x3F, 0x9B, 0x1C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x66, 0x23, 0x90, 0x00, 0x00, -0x00, 0x00, 0x41, 0x84, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x42, 0x46, 0x05, 0x90, 0x00, 0x00, -0x00, 0x00, 0x43, 0x64, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25, 0xE7, 0x90, 0x00, 0x00, -0x00, 0x00, 0x45, 0x43, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0xC9, 0x90, 0x00, 0x00, -0x00, 0x00, 0x47, 0x23, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xEE, 0xE6, 0x10, 0x00, 0x00, -0x00, 0x00, 0x49, 0x03, 0xC1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xCE, 0xC8, 0x10, 0x00, 0x00, -0x00, 0x00, 0x4A, 0xE3, 0xA3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xAE, 0xAA, 0x10, 0x00, 0x00, -0x00, 0x00, 0x4C, 0xCC, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x8E, 0x8C, 0x10, 0x00, 0x00, -0x00, 0x00, 0x4E, 0xAC, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6E, 0x10, 0x00, 0x00, -0x00, 0x00, 0x50, 0x8C, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x57, 0x8A, 0x90, 0x00, 0x00, -0x00, 0x00, 0x52, 0x6C, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x6C, 0x90, 0x00, 0x00, -0x00, 0x00, 0x54, 0x4C, 0x47, 0x90, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x4E, 0x90, 0x00, 0x00, -0x00, 0x00, 0x56, 0x2C, 0x29, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x30, 0x90, 0x00, 0x00, -0x00, 0x00, 0x58, 0x15, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x12, 0x90, 0x00, 0x00, -0x00, 0x00, 0x59, 0xF5, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB6, 0xF4, 0x90, 0x00, 0x00, -0x00, 0x00, 0x5B, 0xD5, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xA0, 0x11, 0x10, 0x00, 0x00, -0x00, 0x00, 0x5D, 0xB4, 0xEC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x7F, 0xF3, 0x10, 0x00, 0x00, -0x00, 0x00, 0x5F, 0x94, 0xCE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5F, 0xD5, 0x10, 0x00, 0x00, -0x00, 0x00, 0x61, 0x7D, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xB7, 0x10, 0x00, 0x00, -0x00, 0x00, 0x63, 0x5D, 0xCC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1F, 0x99, 0x10, 0x00, 0x00, -0x00, 0x00, 0x65, 0x3D, 0xAE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x66, 0x08, 0xB5, 0x90, 0x00, 0x00, -0x00, 0x00, 0x67, 0x1D, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xE8, 0x97, 0x90, 0x00, 0x00, -0x00, 0x00, 0x68, 0xFD, 0x72, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC8, 0x79, 0x90, 0x00, 0x00, -0x00, 0x00, 0x6A, 0xDD, 0x54, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6B, 0xA8, 0x5B, 0x90, 0x00, 0x00, -0x00, 0x00, 0x6C, 0xC6, 0x71, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x88, 0x3D, 0x90, 0x00, 0x00, -0x00, 0x00, 0x6E, 0xA6, 0x53, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x68, 0x1F, 0x90, 0x00, 0x00, -0x00, 0x00, 0x70, 0x86, 0x35, 0x10, 0x00, 0x00, 0x00, 0x00, 0x71, 0x51, 0x3C, 0x10, 0x00, 0x00, -0x00, 0x00, 0x72, 0x66, 0x17, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x31, 0x1E, 0x10, 0x00, 0x00, -0x00, 0x00, 0x74, 0x45, 0xF9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, 0x10, 0x00, 0x00, -0x00, 0x00, 0x76, 0x2F, 0x15, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0xF0, 0xE2, 0x10, 0x00, 0x00, -0x00, 0x00, 0x78, 0x0E, 0xF7, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xD0, 0xC4, 0x10, 0x00, 0x00, -0x00, 0x00, 0x79, 0xEE, 0xD9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xB0, 0xA6, 0x10, 0x00, 0x00, -0x00, 0x00, 0x7B, 0xCE, 0xBB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x99, 0xC2, 0x90, 0x00, 0x00, -0x00, 0x00, 0x7D, 0xAE, 0x9D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x79, 0xA4, 0x90, 0x00, 0x00, -0x00, 0x00, 0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x07, 0x03, -0x07, 0x03, 0x07, 0x03, 0x07, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, -0x09, 0x08, 0x0A, 0x02, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0C, 0x0B, 0x0D, 0x0E, 0x0D, -0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, -0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, -0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, -0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, -0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0D, -0x00, 0x00, 0x20, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x20, 0xD0, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, -0x00, 0x0A, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x12, 0x00, 0x00, -0x1C, 0x20, 0x01, 0x16, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x16, 0x00, 0x00, 0x38, 0x40, 0x01, 0x1B, -0x00, 0x00, 0x2A, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x40, 0x01, 0x1B, 0x00, 0x00, 0x2A, 0x30, -0x01, 0x1F, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1F, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0A, 0x00, 0x00, -0x1C, 0x20, 0x00, 0x0A, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x1F, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, -0x32, 0x32, 0x30, 0x00, 0x45, 0x45, 0x54, 0x00, 0x4D, 0x53, 0x4B, 0x00, 0x43, 0x45, 0x54, 0x00, -0x43, 0x45, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x44, 0x00, 0x45, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x45, 0x45, 0x54, -0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, -0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0xD2, 0x51, 0x25, 0x01, 0x48, -0x51, 0x7A, 0x00, 0x00, 0x00, 0x1B, 0x5A, 0x61, 0x70, 0x6F, 0x72, 0x6F, 0x7A, 0x68, 0x79, 0x65, -0x20, 0x61, 0x6E, 0x64, 0x20, 0x65, 0x61, 0x73, 0x74, 0x20, 0x4C, 0x75, 0x67, 0x61, 0x6E, 0x73, -0x6B, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x45, 0x45, 0x54, 0x2D, 0x32, +0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, +0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, /* Europe/Zurich */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -66100,19 +66108,20 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { /* Pacific/Midway */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x55, 0x4D, 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, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x80, 0x00, 0x00, 0x00, -0xE6, 0x75, 0x8A, 0xB0, 0xE6, 0xED, 0x75, 0x20, 0x7F, 0xFF, 0xFF, 0xFF, 0x01, 0x02, 0x01, 0x01, -0xFF, 0xFF, 0x59, 0xB8, 0x00, 0x00, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, -0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x31, 0x31, 0x00, 0x2D, 0x31, 0x30, 0x00, 0x54, 0x5A, -0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, +0xE6, 0x75, 0x8A, 0xB0, 0xE6, 0xED, 0x75, 0x20, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0x59, 0xB8, 0x00, +0x00, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x08, 0xFF, 0xFF, 0x65, +0x50, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x31, 0x31, 0x00, 0x2D, 0x31, 0x30, 0x00, 0x53, +0x53, 0x54, 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, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x37, -0x5B, 0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x75, 0x8A, 0xB0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0xED, -0x75, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x01, 0x02, 0x01, 0x01, 0xFF, 0xFF, -0x59, 0xB8, 0x00, 0x00, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x08, -0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x31, 0x31, 0x00, 0x2D, 0x31, 0x30, 0x00, 0x0A, 0x3C, 0x2D, 0x31, -0x31, 0x3E, 0x31, 0x31, 0x0A, 0x00, 0xB4, 0x62, 0x62, 0x00, 0x04, 0x04, 0xA5, 0x00, 0x00, 0x00, -0x0E, 0x4D, 0x69, 0x64, 0x77, 0x61, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0xFF, +0xFF, 0xFF, 0xFF, 0x7E, 0x37, 0x5B, 0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x75, 0x8A, 0xB0, 0xFF, +0xFF, 0xFF, 0xFF, 0xE6, 0xED, 0x75, 0x20, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0x59, 0xB8, 0x00, 0x00, +0xFF, 0xFF, 0x65, 0x50, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x08, 0xFF, 0xFF, 0x65, 0x50, +0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x31, 0x31, 0x00, 0x2D, 0x31, 0x30, 0x00, 0x53, 0x53, +0x54, 0x00, 0x0A, 0x53, 0x53, 0x54, 0x31, 0x31, 0x0A, 0x00, 0xB4, 0x62, 0x62, 0x00, 0x04, 0x04, +0xA5, 0x00, 0x00, 0x00, 0x0E, 0x4D, 0x69, 0x64, 0x77, 0x61, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, +0x6E, 0x64, 0x73, /* Pacific/Nauru */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x4E, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -66380,20 +66389,35 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { /* Pacific/Saipan */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x4D, 0x50, 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, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x80, 0x00, 0x00, 0x00, -0xFF, 0x86, 0x37, 0x70, 0x3A, 0x43, 0x5E, 0x60, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0x37, 0x24, 0x00, -0x00, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x08, 0x00, 0x00, 0x8C, -0xA0, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x2B, 0x31, 0x30, 0x00, 0x43, -0x68, 0x53, 0x54, 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, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, -0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xE1, 0xC4, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x36, 0x2C, 0x5C, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x86, 0x37, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x43, 0x5E, 0x60, -0x01, 0x02, 0x03, 0x04, 0xFF, 0xFF, 0x37, 0x24, 0x00, 0x00, 0x00, 0x00, 0x88, 0xA4, 0x00, 0x00, -0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x08, 0x00, 0x00, 0x8C, 0xA0, -0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x2B, 0x31, 0x30, 0x00, 0x43, 0x68, -0x53, 0x54, 0x00, 0x0A, 0x43, 0x68, 0x53, 0x54, 0x2D, 0x31, 0x30, 0x0A, 0x00, 0xA0, 0x85, 0xC0, -0x01, 0xF1, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x00, +0xD0, 0x11, 0x88, 0xF0, 0xEC, 0x37, 0xBE, 0x00, 0xEF, 0x36, 0xF8, 0xF0, 0xFB, 0x9B, 0x00, 0x00, +0xFE, 0x3F, 0x27, 0x8C, 0xFF, 0x01, 0x1E, 0x00, 0xFF, 0x5D, 0x58, 0xF0, 0x00, 0x97, 0x2C, 0x00, +0x01, 0x46, 0x75, 0x70, 0x02, 0x77, 0x0E, 0x00, 0x03, 0x26, 0x57, 0x70, 0x07, 0x70, 0x97, 0x00, +0x07, 0xCC, 0xD1, 0xF0, 0x0C, 0x08, 0x91, 0x00, 0x0C, 0x7C, 0x87, 0x2C, 0x0D, 0xBF, 0x94, 0x80, +0x0E, 0x65, 0xA3, 0x70, 0x3A, 0x43, 0x5E, 0x60, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x04, 0xFF, 0xFF, 0x37, 0x24, 0x00, +0x00, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x08, 0x00, 0x00, 0x8C, +0xA0, 0x00, 0x0C, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x39, +0x00, 0x47, 0x44, 0x54, 0x00, 0x47, 0x53, 0x54, 0x00, 0x43, 0x68, 0x53, 0x54, 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, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xE1, +0xC4, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x36, 0x2C, 0x5C, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x11, +0x88, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x37, 0xBE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x36, +0xF8, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x9B, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, +0x27, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x1E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, +0x58, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x46, +0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x26, +0x57, 0x70, 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xCC, +0xD1, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x08, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x7C, +0x87, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xBF, 0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x65, +0xA3, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x43, 0x5E, 0x60, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, +0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x05, 0xFF, 0xFF, +0x37, 0x24, 0x00, 0x00, 0x00, 0x00, 0x88, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, +0x00, 0x00, 0x9A, 0xB0, 0x01, 0x08, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x0C, 0x00, 0x00, 0x8C, 0xA0, +0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x47, 0x44, 0x54, 0x00, 0x47, 0x53, +0x54, 0x00, 0x43, 0x68, 0x53, 0x54, 0x00, 0x0A, 0x43, 0x68, 0x53, 0x54, 0x2D, 0x31, 0x30, 0x0A, +0x00, 0xA0, 0x85, 0xC0, 0x01, 0xF1, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, /* Pacific/Samoa */ 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -69177,4 +69201,4 @@ const unsigned char timelib_timezone_db_data_builtin[700734] = { }; #endif -const timelib_tzdb timezonedb_builtin = { "2022.2", 596, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; +const timelib_tzdb timezonedb_builtin = { "2022.4", 596, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c index 7740b25e97eb6..b1ab6bd89f49f 100644 --- a/ext/date/lib/tm2unixtime.c +++ b/ext/date/lib/tm2unixtime.c @@ -372,7 +372,7 @@ static void do_adjust_timezone(timelib_time *tz, timelib_tzinfo *tzi) case TIMELIB_ZONETYPE_ID: tzi = tz->tz_info; - /* Break intentionally missing */ + TIMELIB_BREAK_INTENTIONALLY_MISSING default: { /* No timezone in struct, fallback to reference if possible */ diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 3e5de97c6636c..9844618b5b8a1 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3585,7 +3585,7 @@ PHP_FUNCTION(timezone_name_get) PHP_FUNCTION(timezone_name_from_abbr) { zend_string *abbr; - char *tzid; + const char *tzid; zend_long gmtoffset = -1; zend_long isdst = -1; diff --git a/ext/date/tests/gh9165.phpt b/ext/date/tests/gh9165.phpt new file mode 100644 index 0000000000000..d5dce2a1c0832 --- /dev/null +++ b/ext/date/tests/gh9165.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-9165 (strtotime translates a date-time with DST/non-DST hour differently based on default timezone) +--FILE-- + +--EXPECT-- +1540684800 +1540684800 +1540699200 +1540699200 diff --git a/ext/ffi/tests/gh9697.phpt b/ext/ffi/tests/gh9697.phpt new file mode 100644 index 0000000000000..0d73c16bda5cf --- /dev/null +++ b/ext/ffi/tests/gh9697.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-9697 (array_walk($ffiInstance, function () {}) crashes due to expecting mutable array) +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/fileinfo/data_file.c b/ext/fileinfo/data_file.c index 8cc445b115fbc..2a76014904783 100644 --- a/ext/fileinfo/data_file.c +++ b/ext/fileinfo/data_file.c @@ -184490,7 +184490,7 @@ const unsigned char php_magic_database[7015032] = { 0x72, 0x6D, 0x61, 0x74, 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, 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, +0x66, 0x6F, 0x6E, 0x74, 0x2F, 0x77, 0x6F, 0x66, 0x66, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -184500,7 +184500,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3D, 0x04, 0x2E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x6F, 0x66, 0x66, 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, 0x00, 0x00, @@ -184524,7 +184524,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x01, 0x00, 0x10, 0x00, 0x78, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x85, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -184547,7 +184547,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x78, 0x00, 0x07, 0x00, -0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -184571,7 +184571,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x20, 0x00, 0x3D, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x4F, 0x46, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -184584,7 +184584,7 @@ const unsigned char php_magic_database[7015032] = { 0x72, 0x6D, 0x61, 0x74, 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32, 0x29, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x6F, 0x6E, 0x74, 0x2F, 0x77, 0x6F, 0x66, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -184594,7 +184594,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3D, 0x04, 0x2E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x6F, 0x66, 0x66, 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, 0x00, 0x00, @@ -184618,7 +184618,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x01, 0x00, 0x10, 0x00, 0x78, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x8A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x8C, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -184641,7 +184641,7 @@ const unsigned char php_magic_database[7015032] = { 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x78, 0x00, 0x07, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/ext/fileinfo/magicdata.patch b/ext/fileinfo/magicdata.patch index da2323044661e..bfaaa85cc39eb 100644 --- a/ext/fileinfo/magicdata.patch +++ b/ext/fileinfo/magicdata.patch @@ -1,3 +1,20 @@ +diff -ur Magdir.orig/fonts Magdir/fonts +--- Magdir.orig/fonts 2021-02-23 01:49:24.000000000 +0100 ++++ Magdir/fonts 2022-09-18 14:07:14.233023271 +0200 +@@ -384,11 +384,13 @@ + + # https://www.w3.org/TR/WOFF/ + 0 string wOFF Web Open Font Format ++!:mime font/woff + >0 use woff + >20 beshort x \b, version %d + >22 beshort x \b.%d + # https://www.w3.org/TR/WOFF2/ + 0 string wOF2 Web Open Font Format (Version 2) ++!:mime font/woff2 + >0 use woff + #>20 belong x \b, totalCompressedSize %d + >24 beshort x \b, version %d diff -ur Magdir.orig/mail.news Magdir/mail.news --- Magdir.orig/mail.news 2021-03-31 01:47:28.000000000 +0200 +++ Magdir/mail.news 2021-04-05 19:41:55.168556972 +0200 diff --git a/ext/fileinfo/tests/cve-2014-3538-mb.phpt b/ext/fileinfo/tests/cve-2014-3538-mb.phpt index 1cbeaf45a58dd..6e8d32ec56716 100644 --- a/ext/fileinfo/tests/cve-2014-3538-mb.phpt +++ b/ext/fileinfo/tests/cve-2014-3538-mb.phpt @@ -4,6 +4,8 @@ Bug #66731: file: extensive backtracking fileinfo --SKIPIF-- diff --git a/ext/fileinfo/tests/cve-2014-3538.phpt b/ext/fileinfo/tests/cve-2014-3538.phpt index f15e745fc05d3..c5dba2b428c5f 100644 --- a/ext/fileinfo/tests/cve-2014-3538.phpt +++ b/ext/fileinfo/tests/cve-2014-3538.phpt @@ -4,6 +4,8 @@ Bug #66731: file: extensive backtracking fileinfo --SKIPIF-- diff --git a/ext/fileinfo/tests/finfo_file_002.phpt b/ext/fileinfo/tests/finfo_file_002.phpt index 6f852cc353919..51ace0a858522 100644 --- a/ext/fileinfo/tests/finfo_file_002.phpt +++ b/ext/fileinfo/tests/finfo_file_002.phpt @@ -43,4 +43,6 @@ array(%d) { string(11) "image/x-tga" ["%s/resources/test.webm"]=> string(10) "video/webm" + ["%s/resources/test.woff"]=> + string(9) "font/woff" } diff --git a/ext/fileinfo/tests/magic b/ext/fileinfo/tests/magic index d5a9f889294c6..80afcb7b48ace 100644 --- a/ext/fileinfo/tests/magic +++ b/ext/fileinfo/tests/magic @@ -14125,11 +14125,13 @@ # https://www.w3.org/TR/WOFF/ 0 string wOFF Web Open Font Format +!:mime font/woff >0 use woff >20 beshort x \b, version %d >22 beshort x \b.%d # https://www.w3.org/TR/WOFF2/ 0 string wOF2 Web Open Font Format (Version 2) +!:mime font/woff2 >0 use woff #>20 belong x \b, totalCompressedSize %d >24 beshort x \b, version %d diff --git "a/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" "b/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" index d5a9f889294c6..80afcb7b48ace 100644 --- "a/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" +++ "b/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" @@ -14125,11 +14125,13 @@ # https://www.w3.org/TR/WOFF/ 0 string wOFF Web Open Font Format +!:mime font/woff >0 use woff >20 beshort x \b, version %d >22 beshort x \b.%d # https://www.w3.org/TR/WOFF2/ 0 string wOF2 Web Open Font Format (Version 2) +!:mime font/woff2 >0 use woff #>20 belong x \b, totalCompressedSize %d >24 beshort x \b, version %d diff --git a/ext/fileinfo/tests/resources/test.woff b/ext/fileinfo/tests/resources/test.woff new file mode 100644 index 0000000000000..00aa9935f98a4 Binary files /dev/null and b/ext/fileinfo/tests/resources/test.woff differ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 7a093b17741b4..5a261c71453f0 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -743,6 +743,12 @@ PHP_FUNCTION(imageloadfont) font->w = FLIPWORD(font->w); font->h = FLIPWORD(font->h); font->nchars = FLIPWORD(font->nchars); + if (overflow2(font->nchars, font->h) || overflow2(font->nchars * font->h, font->w )) { + php_error_docref(NULL, E_WARNING, "Error reading font, invalid font header"); + efree(font); + php_stream_close(stream); + RETURN_FALSE; + } body_size = font->w * font->h * font->nchars; } @@ -753,6 +759,7 @@ PHP_FUNCTION(imageloadfont) RETURN_FALSE; } + ZEND_ASSERT(body_size > 0); font->data = emalloc(body_size); b = 0; while (b < body_size && (n = php_stream_read(stream, &font->data[b], body_size - b)) > 0) { diff --git a/ext/gd/tests/bug81739.phpt b/ext/gd/tests/bug81739.phpt new file mode 100644 index 0000000000000..cc2a90381bab4 --- /dev/null +++ b/ext/gd/tests/bug81739.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #81739 (OOB read due to insufficient validation in imageloadfont()) +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Warning: imageloadfont(): %croduct of memory allocation multiplication would exceed INT_MAX, failing operation gracefully + in %s on line %d + +Warning: imageloadfont(): Error reading font, invalid font header in %s on line %d +bool(false) \ No newline at end of file diff --git a/ext/hash/sha3/generic32lc/KeccakSponge.inc b/ext/hash/sha3/generic32lc/KeccakSponge.inc index 42a15aac6d936..f8c42ff788b76 100644 --- a/ext/hash/sha3/generic32lc/KeccakSponge.inc +++ b/ext/hash/sha3/generic32lc/KeccakSponge.inc @@ -160,7 +160,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat i = 0; curData = data; while(i < dataByteLen) { - if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { + if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { #ifdef SnP_FastLoop_Absorb /* processing full blocks first */ if ((rateInBytes % (SnP_width/200)) == 0) { @@ -186,9 +186,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat } else { /* normal lane: using the message queue */ - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) + if (dataByteLen-i > rateInBytes-instance->byteIOIndex) partialBlock = rateInBytes-instance->byteIOIndex; + else + partialBlock = (unsigned int)(dataByteLen - i); #ifdef KeccakReference displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); #endif @@ -263,7 +264,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte i = 0; curData = data; while(i < dataByteLen) { - if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { + if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { SnP_Permute(instance->state); SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); @@ -280,9 +281,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte SnP_Permute(instance->state); instance->byteIOIndex = 0; } - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) + if (dataByteLen-i > rateInBytes-instance->byteIOIndex) partialBlock = rateInBytes-instance->byteIOIndex; + else + partialBlock = (unsigned int)(dataByteLen - i); i += partialBlock; SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); diff --git a/ext/hash/sha3/generic64lc/KeccakSponge.inc b/ext/hash/sha3/generic64lc/KeccakSponge.inc index 42a15aac6d936..f8c42ff788b76 100644 --- a/ext/hash/sha3/generic64lc/KeccakSponge.inc +++ b/ext/hash/sha3/generic64lc/KeccakSponge.inc @@ -160,7 +160,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat i = 0; curData = data; while(i < dataByteLen) { - if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { + if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { #ifdef SnP_FastLoop_Absorb /* processing full blocks first */ if ((rateInBytes % (SnP_width/200)) == 0) { @@ -186,9 +186,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat } else { /* normal lane: using the message queue */ - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) + if (dataByteLen-i > rateInBytes-instance->byteIOIndex) partialBlock = rateInBytes-instance->byteIOIndex; + else + partialBlock = (unsigned int)(dataByteLen - i); #ifdef KeccakReference displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); #endif @@ -263,7 +264,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte i = 0; curData = data; while(i < dataByteLen) { - if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { + if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { SnP_Permute(instance->state); SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); @@ -280,9 +281,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte SnP_Permute(instance->state); instance->byteIOIndex = 0; } - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) + if (dataByteLen-i > rateInBytes-instance->byteIOIndex) partialBlock = rateInBytes-instance->byteIOIndex; + else + partialBlock = (unsigned int)(dataByteLen - i); i += partialBlock; SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index c4f77a26fc4dd..a3c23b0ec890f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -251,6 +251,7 @@ static int mbfl_filt_conv_big5_wchar_flush(mbfl_convert_filter *filter) { if (filter->status == 1) { /* 2-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index 7f1994077abfd..ba324eb3016e6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -312,6 +312,7 @@ static int mbfl_filt_conv_cp5022x_wchar_flush(mbfl_convert_filter *filter) /* 2-byte (JIS X 0208 or 0212) character was truncated */ CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); @@ -650,7 +651,7 @@ mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter) CK((*filter->output_function)(0x28, filter->data)); /* '(' */ CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ } - filter->status &= 0xff; + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c index 9bfb75fee8cb0..475e01e970d67 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c @@ -176,6 +176,7 @@ static int mbfl_filt_conv_cp51932_wchar_flush(mbfl_convert_filter *filter) if (filter->status) { /* Input string was truncated */ (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c index 62bf1942193c9..9130cea116324 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c @@ -272,6 +272,7 @@ static int mbfl_filt_conv_cp932_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c index c53bfe42a7b12..e51514aad72d8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c @@ -169,6 +169,7 @@ static int mbfl_filt_conv_cp936_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { /* 2-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c index ecde251b119be..a1e51bbd81473 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c @@ -210,6 +210,7 @@ static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter) { if (filter->status == 1) { /* 2-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c index c963716d43244..b113537b56a48 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c @@ -178,6 +178,7 @@ static int mbfl_filt_conv_eucjp_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c index 02ee1b1c59a19..b7d0705391efe 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c @@ -223,6 +223,7 @@ static int mbfl_filt_conv_eucjpwin_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c index a824909f05c33..6bc52b744b727 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c @@ -197,6 +197,7 @@ static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter) { if (filter->status == 1) { /* 2-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c index 187ac8ad9d558..1cc740dd62e05 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c @@ -243,6 +243,7 @@ static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { /* 2-byte or 4-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c index 5ab2bc15af6f2..7889ad348af23 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c @@ -239,6 +239,7 @@ static int mbfl_filt_conv_gb18030_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { /* multi-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_hz.c b/ext/mbstring/libmbfl/filters/mbfilter_hz.c index 14edf64a7bbac..a9249788aa679 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_hz.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_hz.c @@ -154,6 +154,8 @@ static int mbfl_filt_conv_hz_wchar_flush(mbfl_convert_filter *filter) CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->status = 0; + if (filter->flush_function) { (*filter->flush_function)(filter->data); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c index cc7cd90a1d51a..87ffc37bc3ca8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c @@ -213,6 +213,7 @@ static int mbfl_filt_conv_2022jpms_wchar_flush(mbfl_convert_filter *filter) if (filter->status & 0xF) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); @@ -352,6 +353,7 @@ int mbfl_filt_conv_any_2022jpms_flush(mbfl_convert_filter *filter) CK((*filter->output_function)('(', filter->data)); CK((*filter->output_function)('B', filter->data)); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c index ba1177a2ea985..e01931e397a9a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c @@ -176,6 +176,7 @@ static int mbfl_filt_conv_2022kr_wchar_flush(mbfl_convert_filter *filter) /* 2-byte character was truncated */ CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c index febfd84ddc5ba..9633c76d013d8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c @@ -243,6 +243,7 @@ static int mbfl_filt_conv_2022jp_mobile_wchar_flush(mbfl_convert_filter *filter) if (filter->status & 0xF) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); @@ -358,6 +359,7 @@ static int mbfl_filt_conv_wchar_2022jp_mobile_flush(mbfl_convert_filter *filter) if (filter->status == 1 && (c1 == '#' || (c1 >= '0' && c1 <= '9'))) { (*filter->output_function)(c1, filter->data); } + filter->status = filter->cache = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_jis.c b/ext/mbstring/libmbfl/filters/mbfilter_jis.c index 6d876bbdfad92..d63d972042da5 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_jis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_jis.c @@ -265,6 +265,12 @@ static int mbfl_filt_conv_jis_wchar_flush(mbfl_convert_filter *filter) /* 2-byte (JIS X 0208 or 0212) character was truncated */ CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->status = 0; + + if (filter->flush_function) { + (*filter->flush_function)(filter->data); + } + return 0; } @@ -449,7 +455,7 @@ mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter) CK((*filter->output_function)(0x28, filter->data)); /* '(' */ CK((*filter->output_function)(0x42, filter->data)); /* 'B' */ } - filter->status &= 0xff; + filter->status = 0; if (filter->flush_function != NULL) { return (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c index 96456b26e7eb6..cf03e9cc0db2d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c @@ -179,6 +179,7 @@ static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c index a1d94693e8f83..95816206d5629 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c @@ -24,9 +24,15 @@ /* * The source code included in this files was separated from mbfilter_sjis.c * by rui hirokawa on 15 aug 2011. - * */ +/* Although the specification for Shift-JIS-2004 indicates that 0x5C and + * 0x7E should (respectively) represent a Yen sign and an overbar, feedback + * from Japanese PHP users indicates that they prefer 0x5C and 0x7E to be + * treated as equivalent to U+005C and U+007E. This is the historical + * behavior of mbstring, and promotes compatibility with other software + * which handles Shift-JIS and Shift-JIS-2004 text in this way. */ + #include "mbfilter.h" #include "mbfilter_sjis_2004.h" @@ -421,6 +427,12 @@ int mbfl_filt_conv_jis2004_wchar_flush(mbfl_convert_filter *filter) if (filter->status & 0xF) { CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->status = 0; + + if (filter->flush_function) { + return (*filter->flush_function)(filter->data); + } + return 0; } @@ -489,13 +501,6 @@ int mbfl_filt_conv_wchar_jis2004(int c, mbfl_convert_filter *filter) } } - if (s1 <= 0 && (filter->to->no_encoding == mbfl_no_encoding_2022jp_2004 || filter->to->no_encoding == mbfl_no_encoding_eucjp2004) && (c == 0x5C || c == 0x7E)) { - /* ISO-2022-JP-2004 can represent ASCII characters directly, so there is no need - * to use the JIS X 0208 REVERSE SOLIDUS for ASCII backslash, or WAVE DASH for tilde - * Likewise for EUC-JP-2004 */ - s1 = c; - } - /* check for major japanese chars: U+4E00 - U+9FFF */ if (s1 <= 0) { for (k = 0; k < uni2jis_tbl_len; k++) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c index 35d5bee59a8db..bbc6895ce8fae 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c @@ -264,6 +264,7 @@ mbfl_filt_conv_sjis_mac_wchar(int c, mbfl_convert_filter *filter) static int mbfl_filt_conv_sjis_mac_wchar_flush(mbfl_convert_filter *filter) { if (filter->status == 1) { + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } return 0; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c index 41097df304ac7..f2c230b0cbcb1 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c @@ -717,6 +717,7 @@ static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter) if (filter->status && filter->status != 4) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); @@ -831,6 +832,7 @@ int mbfl_filt_conv_sjis_mobile_flush(mbfl_convert_filter *filter) { int c1 = filter->cache; if (filter->status == 1 && (c1 == '#' || (c1 >= '0' && c1 <= '9'))) { + filter->cache = filter->status = 0; CK((*filter->output_function)(c1, filter->data)); } else if (filter->status == 2) { /* First of a pair of Regional Indicator codepoints came at the end of a string */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c index 388a901fe66d2..3301146a1e9e9 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c @@ -207,6 +207,7 @@ static int mbfl_filt_conv_ucs2_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { /* Input string was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c index 6676f67c3ac22..f0ac949ffda94 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c @@ -289,6 +289,7 @@ static int mbfl_filt_conv_ucs4_wchar_flush(mbfl_convert_filter *filter) /* Input string was truncated */ CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c index 96be552729bfd..60fef4d3952f8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c @@ -145,6 +145,7 @@ static int mbfl_filt_conv_uhc_wchar_flush(mbfl_convert_filter *filter) { if (filter->status == 1) { /* 2-byte character was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf16.c b/ext/mbstring/libmbfl/filters/mbfilter_utf16.c index 71f6e1a0933e9..eb7d9fa2593e1 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf16.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf16.c @@ -313,6 +313,7 @@ static int mbfl_filt_conv_utf16_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { /* Input string was truncated */ + filter->status = 0; CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c index ec9945e13ef50..1269e51500437 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c @@ -222,6 +222,7 @@ static int mbfl_filt_conv_utf32_wchar_flush(mbfl_convert_filter *filter) /* Input string was truncated */ CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); } + filter->cache = filter->status = 0; if (filter->flush_function) { (*filter->flush_function)(filter->data); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c index a5446afd8ae25..bc34a394915ad 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c @@ -277,6 +277,7 @@ static int mbfl_filt_conv_utf7_wchar_flush(mbfl_convert_filter *filter) if (filter->cache) { /* Either we were expecting the 2nd half of a surrogate pair which * never came, or else the last Base64 data was not padded with zeroes */ + filter->cache = 0; (*filter->output_function)(MBFL_BAD_INPUT, filter->data); } @@ -385,6 +386,7 @@ int mbfl_filt_conv_wchar_utf7_flush(mbfl_convert_filter *filter) { int status = filter->status; int cache = filter->cache; + filter->status = filter->cache = 0; /* flush fragments */ switch (status) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c index eb768f9ab2b73..821155f1b71e4 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c @@ -283,6 +283,7 @@ static int mbfl_filt_conv_utf7imap_wchar_flush(mbfl_convert_filter *filter) /* It is illegal for a UTF-7 IMAP string to end in a Base-64 encoded * section. It should always change back to ASCII before the end. */ (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c index 37512b7c8ecba..7ab4c5f96b887 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c @@ -176,6 +176,7 @@ int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter) { if (filter->status) { (*filter->output_function)(MBFL_BAD_INPUT, filter->data); + filter->status = 0; } if (filter->flush_function) { diff --git a/ext/mbstring/libmbfl/filters/unicode_table_jis2004.h b/ext/mbstring/libmbfl/filters/unicode_table_jis2004.h index 09f7c43726178..01afcc1f2d9f4 100644 --- a/ext/mbstring/libmbfl/filters/unicode_table_jis2004.h +++ b/ext/mbstring/libmbfl/filters/unicode_table_jis2004.h @@ -1608,11 +1608,11 @@ static const unsigned short ucs_a1_jisx0213_table[] = { // 0x0000 - 0x045f 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047, 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057, -0x0058,0x0059,0x005A,0x005B,0x2140,0x005D,0x005E,0x005F, +0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, -0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x2141,0x007F, +0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, diff --git a/ext/mbstring/tests/gh9683.phpt b/ext/mbstring/tests/gh9683.phpt new file mode 100644 index 0000000000000..a9c76bffb9f30 --- /dev/null +++ b/ext/mbstring/tests/gh9683.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-9683 (Problem when ISO-2022-JP-MS is specified in mb_ encode_mimeheader) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +1234567890123456789012 diff --git a/ext/mbstring/tests/sjis2004_encoding.phpt b/ext/mbstring/tests/sjis2004_encoding.phpt index eee87240caedd..686b38df7ab43 100644 --- a/ext/mbstring/tests/sjis2004_encoding.phpt +++ b/ext/mbstring/tests/sjis2004_encoding.phpt @@ -38,12 +38,8 @@ while ($line = fgets($fp, 256)) { } } -/* U+007E is TILDE, Shift-JIS 0x8160 is WAVE DASH */ -$fromUnicode["\x00\x7E"] = "\x81\x60"; - -/* U+005C is backslash, Shift-JIS 0x815F is REVERSE SOLIDUS - * (ie. a fancy way to say "backslash") */ -$fromUnicode["\x00\x5C"] = "\x81\x5F"; +$fromUnicode["\x00\x7E"] = "\x7E"; +$fromUnicode["\x00\x5C"] = "\x5C"; testAllValidChars($validChars, 'SJIS-2004', 'UTF-32BE'); echo "SJIS-2004 verification and conversion works for all valid characters\n"; diff --git a/ext/mysqli/tests/gh9590.phpt b/ext/mysqli/tests/gh9590.phpt new file mode 100644 index 0000000000000..eda5dbd844be2 --- /dev/null +++ b/ext/mysqli/tests/gh9590.phpt @@ -0,0 +1,72 @@ +--TEST-- +Bug GH-9602 (stream_select does not abort upon exception or empty valid fd set) +--EXTENSIONS-- +mysqli +posix +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) +bool(true) + +Warning: mysqli_poll(): You MUST recompile PHP with a larger value of FD_SETSIZE. +It is set to 1024, but you have descriptors numbered at least as high as %d. + --enable-fd-setsize=%d is recommended, but you may want to set it +to equal the maximum number of open files supported by your system, +in order to avoid seeing this error again at a later date. in %s on line %d +bool(false) +done! +--CLEAN-- + diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index b0582db10b228..4f720cdb15495 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -2257,7 +2257,9 @@ mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long se DBG_RETURN(FAIL); } - PHP_SAFE_MAX_FD(max_fd, max_set_count); + if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) { + DBG_RETURN(FAIL); + } /* Solaris + BSD do not like microsecond values which are >= 1 sec */ if (usec > 999999) { diff --git a/ext/oci8/tests/conn_attr_1.phpt b/ext/oci8/tests/conn_attr_1.phpt index 4b1b8a3779ad9..a711ab6ccde69 100644 --- a/ext/oci8/tests/conn_attr_1.phpt +++ b/ext/oci8/tests/conn_attr_1.phpt @@ -3,7 +3,9 @@ Set and get of connection attributes with all types of connections. --EXTENSIONS-- oci8 --SKIPIF-- - true, 'timesten' => false); // test runs on these DBs + true, 'timesten' => false); // test runs on these DBs require(__DIR__.'/skipif.inc'); if (strcasecmp($user, "system") && strcasecmp($user, "sys")) diff --git a/ext/oci8/tests/conn_attr_2.phpt b/ext/oci8/tests/conn_attr_2.phpt index 3ffc6b6e0e392..2473eaefaa963 100644 --- a/ext/oci8/tests/conn_attr_2.phpt +++ b/ext/oci8/tests/conn_attr_2.phpt @@ -4,6 +4,7 @@ Set and get of connection attributes across persistent connections and sysdba co oci8 --SKIPIF-- true, 'timesten' => false); // test runs on these DBs require(__DIR__.'/skipif.inc'); diff --git a/ext/oci8/tests/conn_attr_3.phpt b/ext/oci8/tests/conn_attr_3.phpt index 629d9af2e05d8..625f24002b97c 100644 --- a/ext/oci8/tests/conn_attr_3.phpt +++ b/ext/oci8/tests/conn_attr_3.phpt @@ -4,6 +4,7 @@ Set and get of connection attributes with oci_close(). oci8 --SKIPIF-- true, 'timesten' => false); // test runs on these DBs require(__DIR__.'/skipif.inc'); diff --git a/ext/oci8/tests/conn_attr_5.phpt b/ext/oci8/tests/conn_attr_5.phpt index 21ef279466de5..74ae75e301e02 100644 --- a/ext/oci8/tests/conn_attr_5.phpt +++ b/ext/oci8/tests/conn_attr_5.phpt @@ -4,6 +4,7 @@ Set and get connection attributes with scope end. oci8 --SKIPIF-- true, 'timesten' => false); // test runs on these DBs require(__DIR__.'/skipif.inc'); diff --git a/ext/oci8/tests/edition_2.phpt b/ext/oci8/tests/edition_2.phpt index e44fc6035e7ef..ad1884ce4cc06 100644 --- a/ext/oci8/tests/edition_2.phpt +++ b/ext/oci8/tests/edition_2.phpt @@ -4,6 +4,7 @@ Set and check Oracle 11gR2 "edition" attribute oci8 --SKIPIF-- constants_table, q) { + zend_class_constant* c; + if (q->key) { q->key = new_interned_string(q->key); } + c = (zend_class_constant*)Z_PTR(q->val); + if (Z_TYPE(c->value) == IS_STRING) { + ZVAL_STR(&c->value, new_interned_string(Z_STR(c->value))); + } } ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END(); @@ -2204,9 +2210,10 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) /* see bug #15471 (old BTS) */ if (persistent_script->script.filename) { - if (!EG(current_execute_data) || !EG(current_execute_data)->opline || + if (!EG(current_execute_data) || !EG(current_execute_data)->func || !ZEND_USER_CODE(EG(current_execute_data)->func->common.type) || + !EG(current_execute_data)->opline || EG(current_execute_data)->opline->opcode != ZEND_INCLUDE_OR_EVAL || (EG(current_execute_data)->opline->extended_value != ZEND_INCLUDE_ONCE && EG(current_execute_data)->opline->extended_value != ZEND_REQUIRE_ONCE)) { diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 6d5d55790bcf8..11e23cac01b7d 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -4265,24 +4265,30 @@ static int ZEND_FASTCALL zend_runtime_jit(void) zend_op_array *op_array = &EX(func)->op_array; zend_op *opline = op_array->opcodes; zend_jit_op_array_extension *jit_extension; + bool do_bailout = 0; zend_shared_alloc_lock(); if (ZEND_FUNC_INFO(op_array)) { + SHM_UNPROTECT(); zend_jit_unprotect(); - /* restore original opcode handlers */ - if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) { - while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) { - opline++; + zend_try { + /* restore original opcode handlers */ + if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) { + while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) { + opline++; + } } - } - jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); - opline->handler = jit_extension->orig_handler; + jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); + opline->handler = jit_extension->orig_handler; - /* perform real JIT for this function */ - zend_real_jit_func(op_array, NULL, NULL); + /* perform real JIT for this function */ + zend_real_jit_func(op_array, NULL, NULL); + } zend_catch { + do_bailout = 0; + } zend_end_try(); zend_jit_protect(); SHM_PROTECT(); @@ -4290,6 +4296,10 @@ static int ZEND_FASTCALL zend_runtime_jit(void) zend_shared_alloc_unlock(); + if (do_bailout) { + zend_bailout(); + } + /* JIT-ed code is going to be called by VM */ return 0; } @@ -4332,6 +4342,7 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend zend_op_array *op_array = &EX(func)->op_array; zend_jit_op_array_hot_extension *jit_extension; uint32_t i; + bool do_bailout = 0; zend_shared_alloc_lock(); jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(op_array); @@ -4340,12 +4351,16 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend SHM_UNPROTECT(); zend_jit_unprotect(); - for (i = 0; i < op_array->last; i++) { - op_array->opcodes[i].handler = jit_extension->orig_handlers[i]; - } + zend_try { + for (i = 0; i < op_array->last; i++) { + op_array->opcodes[i].handler = jit_extension->orig_handlers[i]; + } - /* perform real JIT for this function */ - zend_real_jit_func(op_array, NULL, opline); + /* perform real JIT for this function */ + zend_real_jit_func(op_array, NULL, opline); + } zend_catch { + do_bailout = 1; + } zend_end_try(); zend_jit_protect(); SHM_PROTECT(); @@ -4353,6 +4368,9 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend zend_shared_alloc_unlock(); + if (do_bailout) { + zend_bailout(); + } /* JIT-ed code is going to be called by VM */ } @@ -5163,6 +5181,10 @@ ZEND_EXT_API void zend_jit_restart(void) if (dasm_buf) { zend_jit_unprotect(); +#if ZEND_JIT_TARGET_ARM64 + memset(dasm_labels_veneers, 0, sizeof(void*) * ZEND_MM_ALIGNED_SIZE_EX(zend_lb_MAX, DASM_ALIGNMENT)); +#endif + /* restore JIT buffer pos */ dasm_ptr[0] = dasm_ptr[1]; diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index d2a8fead2672e..f7bd672392721 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3340,10 +3340,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: - if (opline->op2_type == IS_CV) { - old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var)); - SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), IS_UNKNOWN, 1); - } exit_opline = (trace->opline == opline + 1) ? ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : opline + 1; @@ -3352,6 +3348,16 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra } } + switch (opline->opcode) { + case ZEND_FE_FETCH_R: + case ZEND_FE_FETCH_RW: + if (opline->op2_type != IS_UNUSED) { + old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var)); + SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), IS_UNKNOWN, 1); + } + break; + } + if (opline->result_type == IS_VAR || opline->result_type == IS_TMP_VAR) { old_res_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var)); SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_UNKNOWN, 1); @@ -3365,7 +3371,7 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra switch (opline->opcode) { case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: - if (opline->op2_type == IS_CV) { + if (opline->op2_type != IS_UNUSED) { SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var), old_info); } break; diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index ead3ffa6fd668..5aa450d096bdc 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2688,6 +2688,7 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace const zend_ssa *op_array_ssa; const zend_ssa_op *ssa_op; int i, j, idx, count, level; + int last_idx = -1; int *start, *end; uint8_t *flags; const zend_op_array **vars_op_array; @@ -3092,6 +3093,7 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace } } } else { + last_idx = idx; for (i = 0; i < op_array->last_var; i++) { zend_jit_close_var(stack, i, start, end, flags, idx); } @@ -3401,6 +3403,14 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace } phi = phi->next; } + } else { + for (i = 0; i < ssa->vars_count; i++) { + if (intervals[i] + && intervals[i]->range.end == last_idx + && !(intervals[i]->flags & (ZREG_LOAD|ZREG_STORE))) { + intervals[i]->flags |= ZREG_STORE; + } + } } if (!count) { @@ -6430,7 +6440,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ssa->var_info[ssa_op->op1_def].type &= ~MAY_BE_GUARD; if (ra && ra[ssa_op->op1_def]) { SET_STACK_REG_EX(stack, EX_VAR_TO_NUM(opline->op1.var), ra[ssa_op->op1_def]->reg, - ra[ssa_op->op1_def]->reg & ZREG_STORE); + ra[ssa_op->op1_def]->flags & ZREG_STORE); } } if (type == IS_LONG @@ -7026,6 +7036,7 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace uint8_t orig_trigger; zend_jit_trace_info *t = NULL; zend_jit_trace_exit_info exit_info[ZEND_JIT_TRACE_MAX_EXITS]; + bool do_bailout = 0; zend_shared_alloc_lock(); @@ -7035,97 +7046,106 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace } else if (ZEND_JIT_TRACE_NUM >= JIT_G(max_root_traces)) { ret = ZEND_JIT_TRACE_STOP_TOO_MANY_TRACES; } else { - SHM_UNPROTECT(); - zend_jit_unprotect(); - - t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; - - t->id = ZEND_JIT_TRACE_NUM; - t->root = ZEND_JIT_TRACE_NUM; - t->parent = 0; - t->link = 0; - t->exit_count = 0; - t->child_count = 0; - t->stack_map_size = 0; - t->flags = 0; - t->polymorphism = 0; - t->jmp_table_size = 0; - t->op_array = trace_buffer[0].op_array; - t->opline = trace_buffer[1].opline; - t->exit_info = exit_info; - t->stack_map = NULL; - - orig_trigger = JIT_G(trigger); - JIT_G(trigger) = ZEND_JIT_ON_HOT_TRACE; - - handler = zend_jit_trace(trace_buffer, 0, 0); - - JIT_G(trigger) = orig_trigger; - - if (handler) { - zend_jit_trace_exit_info *shared_exit_info = NULL; - - t->exit_info = NULL; - if (t->exit_count) { - /* reallocate exit_info into shared memory */ - shared_exit_info = (zend_jit_trace_exit_info*)zend_shared_alloc( - sizeof(zend_jit_trace_exit_info) * t->exit_count); - - if (!shared_exit_info) { - if (t->stack_map) { - efree(t->stack_map); - t->stack_map = NULL; - } - ret = ZEND_JIT_TRACE_STOP_NO_SHM; - goto exit; - } - memcpy(shared_exit_info, exit_info, - sizeof(zend_jit_trace_exit_info) * t->exit_count); - t->exit_info = shared_exit_info; - } - - if (t->stack_map_size) { - zend_jit_trace_stack *shared_stack_map = (zend_jit_trace_stack*)zend_shared_alloc(t->stack_map_size * sizeof(zend_jit_trace_stack)); - if (!shared_stack_map) { - ret = ZEND_JIT_TRACE_STOP_NO_SHM; - goto exit; - } - memcpy(shared_stack_map, t->stack_map, t->stack_map_size * sizeof(zend_jit_trace_stack)); - efree(t->stack_map); - t->stack_map = shared_stack_map; - } + zend_try { + SHM_UNPROTECT(); + zend_jit_unprotect(); + + t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; + + t->id = ZEND_JIT_TRACE_NUM; + t->root = ZEND_JIT_TRACE_NUM; + t->parent = 0; + t->link = 0; + t->exit_count = 0; + t->child_count = 0; + t->stack_map_size = 0; + t->flags = 0; + t->polymorphism = 0; + t->jmp_table_size = 0; + t->op_array = trace_buffer[0].op_array; + t->opline = trace_buffer[1].opline; + t->exit_info = exit_info; + t->stack_map = NULL; + + orig_trigger = JIT_G(trigger); + JIT_G(trigger) = ZEND_JIT_ON_HOT_TRACE; + + handler = zend_jit_trace(trace_buffer, 0, 0); + + JIT_G(trigger) = orig_trigger; + + if (handler) { + zend_jit_trace_exit_info *shared_exit_info = NULL; + + t->exit_info = NULL; + if (t->exit_count) { + /* reallocate exit_info into shared memory */ + shared_exit_info = (zend_jit_trace_exit_info*)zend_shared_alloc( + sizeof(zend_jit_trace_exit_info) * t->exit_count); + + if (!shared_exit_info) { + if (t->stack_map) { + efree(t->stack_map); + t->stack_map = NULL; + } + ret = ZEND_JIT_TRACE_STOP_NO_SHM; + goto exit; + } + memcpy(shared_exit_info, exit_info, + sizeof(zend_jit_trace_exit_info) * t->exit_count); + t->exit_info = shared_exit_info; + } + + if (t->stack_map_size) { + zend_jit_trace_stack *shared_stack_map = (zend_jit_trace_stack*)zend_shared_alloc(t->stack_map_size * sizeof(zend_jit_trace_stack)); + if (!shared_stack_map) { + ret = ZEND_JIT_TRACE_STOP_NO_SHM; + goto exit; + } + memcpy(shared_stack_map, t->stack_map, t->stack_map_size * sizeof(zend_jit_trace_stack)); + efree(t->stack_map); + t->stack_map = shared_stack_map; + } - t->exit_counters = ZEND_JIT_EXIT_COUNTERS; - ZEND_JIT_EXIT_COUNTERS += t->exit_count; + t->exit_counters = ZEND_JIT_EXIT_COUNTERS; + ZEND_JIT_EXIT_COUNTERS += t->exit_count; - ((zend_op*)opline)->handler = handler; + ((zend_op*)opline)->handler = handler; - ZEND_JIT_TRACE_NUM++; - ZEND_OP_TRACE_INFO(opline, offset)->trace_flags |= ZEND_JIT_TRACE_JITED; + ZEND_JIT_TRACE_NUM++; + ZEND_OP_TRACE_INFO(opline, offset)->trace_flags |= ZEND_JIT_TRACE_JITED; - ret = ZEND_JIT_TRACE_STOP_COMPILED; - } else if (t->exit_count >= ZEND_JIT_TRACE_MAX_EXITS || - ZEND_JIT_EXIT_COUNTERS + t->exit_count >= JIT_G(max_exit_counters)) { - if (t->stack_map) { - efree(t->stack_map); - t->stack_map = NULL; - } - ret = ZEND_JIT_TRACE_STOP_TOO_MANY_EXITS; - } else { - if (t->stack_map) { - efree(t->stack_map); - t->stack_map = NULL; + ret = ZEND_JIT_TRACE_STOP_COMPILED; + } else if (t->exit_count >= ZEND_JIT_TRACE_MAX_EXITS || + ZEND_JIT_EXIT_COUNTERS + t->exit_count >= JIT_G(max_exit_counters)) { + if (t->stack_map) { + efree(t->stack_map); + t->stack_map = NULL; + } + ret = ZEND_JIT_TRACE_STOP_TOO_MANY_EXITS; + } else { + if (t->stack_map) { + efree(t->stack_map); + t->stack_map = NULL; + } + ret = ZEND_JIT_TRACE_STOP_COMPILER_ERROR; } - ret = ZEND_JIT_TRACE_STOP_COMPILER_ERROR; - } -exit: +exit:; + } zend_catch { + do_bailout = 1; + } zend_end_try(); + zend_jit_protect(); SHM_PROTECT(); } zend_shared_alloc_unlock(); + if (do_bailout) { + zend_bailout(); + } + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) != 0 && ret == ZEND_JIT_TRACE_STOP_COMPILED && t->exit_count > 0) { @@ -7612,6 +7632,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const static void zend_jit_blacklist_trace_exit(uint32_t trace_num, uint32_t exit_num) { const void *handler; + bool do_bailout = 0; zend_shared_alloc_lock(); @@ -7619,24 +7640,31 @@ static void zend_jit_blacklist_trace_exit(uint32_t trace_num, uint32_t exit_num) SHM_UNPROTECT(); zend_jit_unprotect(); - handler = zend_jit_trace_exit_to_vm(trace_num, exit_num); + zend_try { + handler = zend_jit_trace_exit_to_vm(trace_num, exit_num); - if (handler) { - zend_jit_link_side_trace( - zend_jit_traces[trace_num].code_start, - zend_jit_traces[trace_num].code_size, - zend_jit_traces[trace_num].jmp_table_size, - exit_num, - handler); - } - - zend_jit_traces[trace_num].exit_info[exit_num].flags |= ZEND_JIT_EXIT_BLACKLISTED; + if (handler) { + zend_jit_link_side_trace( + zend_jit_traces[trace_num].code_start, + zend_jit_traces[trace_num].code_size, + zend_jit_traces[trace_num].jmp_table_size, + exit_num, + handler); + } + zend_jit_traces[trace_num].exit_info[exit_num].flags |= ZEND_JIT_EXIT_BLACKLISTED; + } zend_catch { + do_bailout = 1; + } zend_end_try(); zend_jit_protect(); SHM_PROTECT(); } zend_shared_alloc_unlock(); + + if (do_bailout) { + zend_bailout(); + } } static bool zend_jit_trace_exit_is_bad(uint32_t trace_num, uint32_t exit_num) @@ -7670,6 +7698,7 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace uint8_t orig_trigger; zend_jit_trace_info *t; zend_jit_trace_exit_info exit_info[ZEND_JIT_TRACE_MAX_EXITS]; + bool do_bailout = 0; zend_shared_alloc_lock(); @@ -7684,100 +7713,109 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace SHM_UNPROTECT(); zend_jit_unprotect(); - t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; + zend_try { + t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; - t->id = ZEND_JIT_TRACE_NUM; - t->root = zend_jit_traces[parent_num].root; - t->parent = parent_num; - t->link = 0; - t->exit_count = 0; - t->child_count = 0; - t->stack_map_size = 0; - t->flags = 0; - t->polymorphism = polymorphism; - t->jmp_table_size = 0; - t->opline = NULL; - t->exit_info = exit_info; - t->stack_map = NULL; + t->id = ZEND_JIT_TRACE_NUM; + t->root = zend_jit_traces[parent_num].root; + t->parent = parent_num; + t->link = 0; + t->exit_count = 0; + t->child_count = 0; + t->stack_map_size = 0; + t->flags = 0; + t->polymorphism = polymorphism; + t->jmp_table_size = 0; + t->opline = NULL; + t->exit_info = exit_info; + t->stack_map = NULL; - orig_trigger = JIT_G(trigger); - JIT_G(trigger) = ZEND_JIT_ON_HOT_TRACE; + orig_trigger = JIT_G(trigger); + JIT_G(trigger) = ZEND_JIT_ON_HOT_TRACE; - handler = zend_jit_trace(trace_buffer, parent_num, exit_num); + handler = zend_jit_trace(trace_buffer, parent_num, exit_num); - JIT_G(trigger) = orig_trigger; + JIT_G(trigger) = orig_trigger; - if (handler) { - zend_jit_trace_exit_info *shared_exit_info = NULL; + if (handler) { + zend_jit_trace_exit_info *shared_exit_info = NULL; - t->exit_info = NULL; - if (t->exit_count) { - /* reallocate exit_info into shared memory */ - shared_exit_info = (zend_jit_trace_exit_info*)zend_shared_alloc( - sizeof(zend_jit_trace_exit_info) * t->exit_count); + t->exit_info = NULL; + if (t->exit_count) { + /* reallocate exit_info into shared memory */ + shared_exit_info = (zend_jit_trace_exit_info*)zend_shared_alloc( + sizeof(zend_jit_trace_exit_info) * t->exit_count); - if (!shared_exit_info) { - if (t->stack_map) { - efree(t->stack_map); - t->stack_map = NULL; + if (!shared_exit_info) { + if (t->stack_map) { + efree(t->stack_map); + t->stack_map = NULL; + } + ret = ZEND_JIT_TRACE_STOP_NO_SHM; + goto exit; } - ret = ZEND_JIT_TRACE_STOP_NO_SHM; - goto exit; + memcpy(shared_exit_info, exit_info, + sizeof(zend_jit_trace_exit_info) * t->exit_count); + t->exit_info = shared_exit_info; } - memcpy(shared_exit_info, exit_info, - sizeof(zend_jit_trace_exit_info) * t->exit_count); - t->exit_info = shared_exit_info; - } - if (t->stack_map_size) { - zend_jit_trace_stack *shared_stack_map = (zend_jit_trace_stack*)zend_shared_alloc(t->stack_map_size * sizeof(zend_jit_trace_stack)); - if (!shared_stack_map) { + if (t->stack_map_size) { + zend_jit_trace_stack *shared_stack_map = (zend_jit_trace_stack*)zend_shared_alloc(t->stack_map_size * sizeof(zend_jit_trace_stack)); + if (!shared_stack_map) { + efree(t->stack_map); + ret = ZEND_JIT_TRACE_STOP_NO_SHM; + goto exit; + } + memcpy(shared_stack_map, t->stack_map, t->stack_map_size * sizeof(zend_jit_trace_stack)); efree(t->stack_map); - ret = ZEND_JIT_TRACE_STOP_NO_SHM; - goto exit; - } - memcpy(shared_stack_map, t->stack_map, t->stack_map_size * sizeof(zend_jit_trace_stack)); - efree(t->stack_map); - t->stack_map = shared_stack_map; - } - - zend_jit_link_side_trace( - zend_jit_traces[parent_num].code_start, - zend_jit_traces[parent_num].code_size, - zend_jit_traces[parent_num].jmp_table_size, - exit_num, - handler); - - t->exit_counters = ZEND_JIT_EXIT_COUNTERS; - ZEND_JIT_EXIT_COUNTERS += t->exit_count; - - zend_jit_traces[zend_jit_traces[parent_num].root].child_count++; - ZEND_JIT_TRACE_NUM++; - zend_jit_traces[parent_num].exit_info[exit_num].flags |= ZEND_JIT_EXIT_JITED; - - ret = ZEND_JIT_TRACE_STOP_COMPILED; - } else if (t->exit_count >= ZEND_JIT_TRACE_MAX_EXITS || - ZEND_JIT_EXIT_COUNTERS + t->exit_count >= JIT_G(max_exit_counters)) { - if (t->stack_map) { - efree(t->stack_map); - t->stack_map = NULL; - } - ret = ZEND_JIT_TRACE_STOP_TOO_MANY_EXITS; - } else { - if (t->stack_map) { - efree(t->stack_map); - t->stack_map = NULL; + t->stack_map = shared_stack_map; + } + + zend_jit_link_side_trace( + zend_jit_traces[parent_num].code_start, + zend_jit_traces[parent_num].code_size, + zend_jit_traces[parent_num].jmp_table_size, + exit_num, + handler); + + t->exit_counters = ZEND_JIT_EXIT_COUNTERS; + ZEND_JIT_EXIT_COUNTERS += t->exit_count; + + zend_jit_traces[zend_jit_traces[parent_num].root].child_count++; + ZEND_JIT_TRACE_NUM++; + zend_jit_traces[parent_num].exit_info[exit_num].flags |= ZEND_JIT_EXIT_JITED; + + ret = ZEND_JIT_TRACE_STOP_COMPILED; + } else if (t->exit_count >= ZEND_JIT_TRACE_MAX_EXITS || + ZEND_JIT_EXIT_COUNTERS + t->exit_count >= JIT_G(max_exit_counters)) { + if (t->stack_map) { + efree(t->stack_map); + t->stack_map = NULL; + } + ret = ZEND_JIT_TRACE_STOP_TOO_MANY_EXITS; + } else { + if (t->stack_map) { + efree(t->stack_map); + t->stack_map = NULL; + } + ret = ZEND_JIT_TRACE_STOP_COMPILER_ERROR; } - ret = ZEND_JIT_TRACE_STOP_COMPILER_ERROR; - } -exit: +exit:; + } zend_catch { + do_bailout = 1; + } zend_end_try(); + zend_jit_protect(); SHM_PROTECT(); } zend_shared_alloc_unlock(); + if (do_bailout) { + zend_bailout(); + } + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) != 0 && ret == ZEND_JIT_TRACE_STOP_COMPILED && t->exit_count > 0) { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ba6e52abbccb0..ad80a3b62909e 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -152,6 +152,11 @@ static size_t tsrm_tls_offset; #define IS_SIGNED_32BIT(val) ((((intptr_t)(val)) <= 0x7fffffff) && (((intptr_t)(val)) >= (-2147483647 - 1))) +/* Call range is before or after 2GB */ +#define MAY_USE_32BIT_ADDR(addr) \ + (IS_SIGNED_32BIT((char*)(addr) - (char*)dasm_buf) && \ + IS_SIGNED_32BIT((char*)(addr) - (char*)dasm_end)) + #define CAN_USE_AVX() (JIT_G(opt_flags) & allowed_opt_flags & ZEND_JIT_CPU_AVX) /* Not Implemented Yet */ @@ -353,7 +358,7 @@ static size_t tsrm_tls_offset; |.macro EXT_CALL, func, tmp_reg | .if X64 -|| if (IS_32BIT(dasm_end) && IS_32BIT(func)) { +|| if (MAY_USE_32BIT_ADDR(func)) { | call qword &func || } else { | LOAD_ADDR tmp_reg, func @@ -366,7 +371,7 @@ static size_t tsrm_tls_offset; |.macro EXT_JMP, func, tmp_reg | .if X64 -|| if (IS_32BIT(dasm_end) && IS_32BIT(func)) { +|| if (MAY_USE_32BIT_ADDR(func)) { | jmp qword &func || } else { | LOAD_ADDR tmp_reg, func @@ -3612,11 +3617,13 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra opline->opcode == ZEND_GENERATOR_CREATE) { if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { -#if 0 - /* this check should be handled by the following OPLINE guard or jmp [IP] */ - | cmp IP, zend_jit_halt_op - | je ->trace_halt -#endif + if (trace->op != ZEND_JIT_TRACE_END || + (trace->stop != ZEND_JIT_TRACE_STOP_RETURN && + trace->stop != ZEND_JIT_TRACE_STOP_INTERPRETER)) { + /* this check may be handled by the following OPLINE guard or jmp [IP] */ + | cmp IP, zend_jit_halt_op + | je ->trace_halt + } } else if (GCC_GLOBAL_REGS) { | test IP, IP | je ->trace_halt @@ -3667,10 +3674,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: - if (opline->op2_type == IS_CV) { - old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var)); - SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), IS_UNKNOWN, 1); - } exit_opline = (trace->opline == opline + 1) ? ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : opline + 1; @@ -3679,6 +3682,16 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra } } + switch (opline->opcode) { + case ZEND_FE_FETCH_R: + case ZEND_FE_FETCH_RW: + if (opline->op2_type != IS_UNUSED) { + old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var)); + SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), IS_UNKNOWN, 1); + } + break; + } + if (opline->result_type == IS_VAR || opline->result_type == IS_TMP_VAR) { old_res_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var)); SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_UNKNOWN, 1); @@ -3692,7 +3705,7 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra switch (opline->opcode) { case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: - if (opline->op2_type == IS_CV) { + if (opline->op2_type != IS_UNUSED) { SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var), old_info); } break; diff --git a/ext/opcache/tests/jit/reg_alloc_017.phpt b/ext/opcache/tests/jit/reg_alloc_017.phpt new file mode 100644 index 0000000000000..361ab2d81587f --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_017.phpt @@ -0,0 +1,21 @@ +--TEST-- +Register Alloction 017: Missing store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/phar/phar.c b/ext/phar/phar.c index bc08e4edde05d..b45586d1e8fad 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1627,6 +1627,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char const char gz_magic[] = "\x1f\x8b\x08"; const char bz_magic[] = "BZh"; char *pos, test = '\0'; + int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion const int window_size = 1024; char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */ const zend_long readsize = sizeof(buffer) - sizeof(token); @@ -1654,7 +1655,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)") } - if (!test) { + if (!test && recursion_count) { test = '\1'; pos = buffer+tokenlen; if (!memcmp(pos, gz_magic, 3)) { @@ -1716,6 +1717,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char /* now, start over */ test = '\0'; + if (!--recursion_count) { + MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\""); + break; + } continue; } else if (!memcmp(pos, bz_magic, 3)) { php_stream_filter *filter; @@ -1754,6 +1759,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char /* now, start over */ test = '\0'; + if (!--recursion_count) { + MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\""); + break; + } continue; } diff --git a/ext/phar/tests/bug81726.gz b/ext/phar/tests/bug81726.gz new file mode 100644 index 0000000000000..67b41ba3b6567 Binary files /dev/null and b/ext/phar/tests/bug81726.gz differ diff --git a/ext/phar/tests/bug81726.phpt b/ext/phar/tests/bug81726.phpt new file mode 100644 index 0000000000000..a86c52a64980f --- /dev/null +++ b/ext/phar/tests/bug81726.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #81726 (phar wrapper: DOS when using quine gzip file) +--EXTENSIONS-- +phar +zlib +--FILE-- + +--EXPECTF-- +Warning: fopen(phar://%s): Failed to open stream: unable to decompress gzipped phar archive "%s" in %s on line %d +bool(false) diff --git a/ext/session/session.c b/ext/session/session.c index 18444932ceb37..836f204fd4962 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1082,6 +1082,8 @@ PHPAPI int php_session_register_module(const ps_module *ptr) /* {{{ */ /* }}} */ /* Dummy PS module function */ +/* We consider any ID valid (thus also implying that a session with such an ID exists), + thus we always return SUCCESS */ PHPAPI int php_session_validate_sid(PS_VALIDATE_SID_ARGS) { return SUCCESS; } @@ -2258,18 +2260,24 @@ PHP_FUNCTION(session_regenerate_id) } RETURN_THROWS(); } - if (PS(use_strict_mode) && PS(mod)->s_validate_sid && - PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == SUCCESS) { - zend_string_release_ex(PS(id), 0); - PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); - if (!PS(id)) { - PS(mod)->s_close(&PS(mod_data)); - PS(session_status) = php_session_none; - if (!EG(exception)) { - zend_throw_error(NULL, "Failed to create session ID by collision: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + if (PS(use_strict_mode)) { + if ((!PS(mod_user_implemented) && PS(mod)->s_validate_sid) || !Z_ISUNDEF(PS(mod_user_names).name.ps_validate_sid)) { + int limit = 3; + /* Try to generate non-existing ID */ + while (limit-- && PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == SUCCESS) { + zend_string_release_ex(PS(id), 0); + PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); + if (!PS(id)) { + PS(mod)->s_close(&PS(mod_data)); + PS(session_status) = php_session_none; + if (!EG(exception)) { + zend_throw_error(NULL, "Failed to create session ID by collision: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + } + RETURN_THROWS(); + } } - RETURN_THROWS(); } + // TODO warn that ID cannot be verified? else { } } /* Read is required to make new session data at this point. */ if (PS(mod)->s_read(&PS(mod_data), PS(id), &data, PS(gc_maxlifetime)) == FAILURE) { @@ -2296,7 +2304,6 @@ PHP_FUNCTION(session_regenerate_id) /* }}} */ /* {{{ Generate new session ID. Intended for user save handlers. */ -/* This is not used yet */ PHP_FUNCTION(session_create_id) { zend_string *prefix = NULL, *new_id; @@ -2320,7 +2327,7 @@ PHP_FUNCTION(session_create_id) int limit = 3; while (limit--) { new_id = PS(mod)->s_create_sid(&PS(mod_data)); - if (!PS(mod)->s_validate_sid) { + if (!PS(mod)->s_validate_sid || (PS(mod_user_implemented) && Z_ISUNDEF(PS(mod_user_names).name.ps_validate_sid))) { break; } else { /* Detect collision and retry */ diff --git a/ext/session/tests/gh9583-extra.phpt b/ext/session/tests/gh9583-extra.phpt new file mode 100644 index 0000000000000..4332dd9b3eb12 --- /dev/null +++ b/ext/session/tests/gh9583-extra.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-9583: session_create_id() fails with user defined save handler that doesn't have a validateId() method +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- +validateId(1) ? 'true' : 'false')) : 'is commented out'), "\n"; +var_dump($originalSessionId == $newSessionId); + +?> +--EXPECT-- +validateId() is commented out +bool(true) diff --git a/ext/session/tests/gh9583.phpt b/ext/session/tests/gh9583.phpt new file mode 100644 index 0000000000000..2c2af24b5c197 --- /dev/null +++ b/ext/session/tests/gh9583.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-9583: session_create_id() fails with user defined save handler that doesn't have a validateId() method +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- +validateId(1)?'true':'false')):'is commented out'); +echo "\n"; +$sessionId = session_create_id(); +echo "\nSession ID:".$sessionId; +echo "\n"; + +?> +--EXPECTF-- +validateId() is commented out + +Session ID:%s diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 8a46446785f45..4b269d8cb0d4d 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -770,7 +770,9 @@ PHP_FUNCTION(socket_select) RETURN_THROWS(); } - PHP_SAFE_MAX_FD(max_fd, 0); /* someone needs to make this look more like stream_socket_select */ + if (!PHP_SAFE_MAX_FD(max_fd, 0)) { + RETURN_FALSE; + } /* If seconds is not set to null, build the timeval, else we wait indefinitely */ if (!sec_is_null) { diff --git a/ext/sockets/tests/socket_cmsg_credentials.phpt b/ext/sockets/tests/socket_cmsg_credentials.phpt index 7402c9437c2b2..02079ff1f1f5e 100644 --- a/ext/sockets/tests/socket_cmsg_credentials.phpt +++ b/ext/sockets/tests/socket_cmsg_credentials.phpt @@ -17,7 +17,7 @@ die('skip SO_PASSCRED is not defined'); --FILE-- --CLEAN-- +--CLEAN-- +fci; + if (zend_hash_num_elements(target_hash) == 0) { + return result; + } + /* Set up known arguments */ ZVAL_UNDEF(&args[1]); if (userdata) { diff --git a/ext/standard/php_crypt_r.c b/ext/standard/php_crypt_r.c index d1d968ba27a7c..bd30ce9ce8cbb 100644 --- a/ext/standard/php_crypt_r.c +++ b/ext/standard/php_crypt_r.c @@ -47,14 +47,14 @@ MUTEX_T php_crypt_extended_init_lock; #endif -void php_init_crypt_r() +void php_init_crypt_r(void) { #ifdef ZTS php_crypt_extended_init_lock = tsrm_mutex_alloc(); #endif } -void php_shutdown_crypt_r() +void php_shutdown_crypt_r(void) { #ifdef ZTS tsrm_mutex_free(php_crypt_extended_init_lock); diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 5335a47291b5a..13f3ead5aecf8 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -799,7 +799,9 @@ PHP_FUNCTION(stream_select) RETURN_THROWS(); } - PHP_SAFE_MAX_FD(max_fd, max_set_count); + if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) { + RETURN_FALSE; + } if (secnull && !usecnull) { if (usec != 0) { diff --git a/ext/standard/tests/bug81727.phpt b/ext/standard/tests/bug81727.phpt new file mode 100644 index 0000000000000..71a9cb46c83be --- /dev/null +++ b/ext/standard/tests/bug81727.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #81727: $_COOKIE name starting with ..Host/..Secure should be discarded +--COOKIE-- +..Host-test=ignore; __Host-test=correct; . Secure-test=ignore; . Elephpant=Awesome; +--FILE-- + +--EXPECT-- +array(2) { + ["__Host-test"]=> + string(7) "correct" + ["__Elephpant"]=> + string(7) "Awesome" +} diff --git a/ext/standard/tests/file/windows_acls/common.inc b/ext/standard/tests/file/windows_acls/common.inc index b3490ebb432ba..8e69d23b35a66 100644 --- a/ext/standard/tests/file/windows_acls/common.inc +++ b/ext/standard/tests/file/windows_acls/common.inc @@ -16,6 +16,11 @@ function skipif() { if(stripos(php_uname(), 'XP') !== FALSE) { die('skip windows 2003 or newer only test'); } + if (getenv('GITHUB_ACTIONS')) { + // bug44859_4.phpt test fails on the 1st run + // other ACL tests cannot be run twice + die('skip failing on Github Actions (but passes in AppVeyor)'); + } } function get_username(){ diff --git a/ext/standard/tests/network/bug73594.phpt b/ext/standard/tests/network/bug73594.phpt index 79607cacec0cd..370b6162fde9e 100644 --- a/ext/standard/tests/network/bug73594.phpt +++ b/ext/standard/tests/network/bug73594.phpt @@ -24,4 +24,4 @@ $res = dns_get_record('php.net', DNS_MX, $auth, $additional); var_dump(!empty($res) && empty($additional)); ?> --EXPECT-- -bool(true) +bool(false) diff --git a/ext/standard/tests/streams/gh9590-001.phpt b/ext/standard/tests/streams/gh9590-001.phpt new file mode 100644 index 0000000000000..558e4660a65f8 --- /dev/null +++ b/ext/standard/tests/streams/gh9590-001.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug GH-9590 001 (stream_select does not abort upon exception or empty valid fd set) +--EXTENSIONS-- +posix +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE. +It is set to 1024, but you have descriptors numbered at least as high as %d. + --enable-fd-setsize=%d is recommended, but you may want to set it +to equal the maximum number of open files supported by your system, +in order to avoid seeing this error again at a later date. in %s on line %d +bool(false) +--CLEAN-- + diff --git a/ext/standard/tests/streams/gh9590-002.phpt b/ext/standard/tests/streams/gh9590-002.phpt new file mode 100644 index 0000000000000..55c1c6d0282bc --- /dev/null +++ b/ext/standard/tests/streams/gh9590-002.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug GH-9590 002 (stream_select does not abort upon exception or empty valid fd set) +--EXTENSIONS-- +posix +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE. +It is set to 1024, but you have descriptors numbered at least as high as %d. + --enable-fd-setsize=%d is recommended, but you may want to set it +to equal the maximum number of open files supported by your system, +in order to avoid seeing this error again at a later date. in %s:%d +Stack trace:%a +--CLEAN-- + diff --git a/main/network.c b/main/network.c index 1ad7e370cca63..b4799791bd3be 100644 --- a/main/network.c +++ b/main/network.c @@ -1194,7 +1194,14 @@ PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout) } #endif - PHP_SAFE_MAX_FD(max_fd, nfds + 1); + if (!PHP_SAFE_MAX_FD(max_fd, nfds + 1)) { +#ifdef PHP_WIN32 + WSASetLastError(WSAEINVAL); +#else + errno = ERANGE; +#endif + return -1; + } FD_ZERO(&rset); FD_ZERO(&wset); diff --git a/main/php_network.h b/main/php_network.h index aafdfaa1ef9cb..989d1a34b99f7 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -211,18 +211,35 @@ static inline int php_pollfd_for_ms(php_socket_t fd, int events, int timeout) /* emit warning and suggestion for unsafe select(2) usage */ PHPAPI void _php_emit_fd_setsize_warning(int max_fd); +static inline bool _php_check_fd_setsize(php_socket_t *max_fd, int setsize) +{ +#ifdef PHP_WIN32 + if (setsize + 1 >= FD_SETSIZE) { + _php_emit_fd_setsize_warning(setsize); + return false; + } +#else + if (*max_fd >= FD_SETSIZE) { + _php_emit_fd_setsize_warning(*max_fd); + *max_fd = FD_SETSIZE - 1; + return false; + } +#endif + return true; +} + #ifdef PHP_WIN32 /* it is safe to FD_SET too many fd's under win32; the macro will simply ignore * descriptors that go beyond the default FD_SETSIZE */ # define PHP_SAFE_FD_SET(fd, set) FD_SET(fd, set) # define PHP_SAFE_FD_CLR(fd, set) FD_CLR(fd, set) # define PHP_SAFE_FD_ISSET(fd, set) FD_ISSET(fd, set) -# define PHP_SAFE_MAX_FD(m, n) do { if (n + 1 >= FD_SETSIZE) { _php_emit_fd_setsize_warning(n); }} while(0) +# define PHP_SAFE_MAX_FD(m, n) _php_check_fd_setsize(&m, n) #else # define PHP_SAFE_FD_SET(fd, set) do { if (fd < FD_SETSIZE) FD_SET(fd, set); } while(0) # define PHP_SAFE_FD_CLR(fd, set) do { if (fd < FD_SETSIZE) FD_CLR(fd, set); } while(0) # define PHP_SAFE_FD_ISSET(fd, set) ((fd < FD_SETSIZE) && FD_ISSET(fd, set)) -# define PHP_SAFE_MAX_FD(m, n) do { if (m >= FD_SETSIZE) { _php_emit_fd_setsize_warning(m); m = FD_SETSIZE - 1; }} while(0) +# define PHP_SAFE_MAX_FD(m, n) _php_check_fd_setsize(&m, n) #endif diff --git a/main/php_variables.c b/main/php_variables.c index 0261cf0098ee4..17e4a1e5d2cf1 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -104,6 +104,20 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac } var_len = p - var; + /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */ + if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) { + zval_ptr_dtor_nogc(val); + free_alloca(var_orig, use_heap); + return; + } + + /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */ + if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) { + zval_ptr_dtor_nogc(val); + free_alloca(var_orig, use_heap); + return; + } + if (var_len==0) { /* empty variable name, or variable name with a space in it */ zval_ptr_dtor_nogc(val); free_alloca(var_orig, use_heap); diff --git a/main/php_version.h b/main/php_version.h index baf7b8c6b1893..7dede60b94ffa 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 -#define PHP_RELEASE_VERSION 11 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.11-dev" -#define PHP_VERSION_ID 80111 +#define PHP_RELEASE_VERSION 12 +#define PHP_EXTRA_VERSION "" +#define PHP_VERSION "8.1.12" +#define PHP_VERSION_ID 80112 diff --git a/sapi/fpm/tests/bug74083-concurrent-reload.phpt b/sapi/fpm/tests/bug74083-concurrent-reload.phpt index 8b4b690e96201..ad5d560abae47 100644 --- a/sapi/fpm/tests/bug74083-concurrent-reload.phpt +++ b/sapi/fpm/tests/bug74083-concurrent-reload.phpt @@ -50,17 +50,11 @@ for ($interval = 0; $interval < $max_interval; $interval += $step) { usleep($interval); } echo "Reached interval $interval us with $step us steps\n"; -$tester->expectLogNotice('Reloading in progress ...'); -/* Consume mix of 'Reloading in progress ...' and 'reloading: .*' */ -$tester->getLogLines(2000); +$tester->readAllLogNotices('Reloading in progress ...'); -$tester->signal('USR2'); -$tester->expectLogNotice('Reloading in progress ...'); -$tester->expectLogNotice('reloading: .*'); -$tester->expectLogNotice('using inherited socket fd=\d+, "127.0.0.1:\d+"'); -$tester->expectLogStartNotices(); +$tester->reload(); +$tester->expectLogReloadingNotices(); $tester->ping('{{ADDR}}'); - $tester->terminate(); $tester->expectLogTerminatingNotices(); $tester->close(); diff --git a/sapi/fpm/tests/bug76601-reload-child-signals.phpt b/sapi/fpm/tests/bug76601-reload-child-signals.phpt index f095ed667ca83..1a3e6d2b74fb0 100644 --- a/sapi/fpm/tests/bug76601-reload-child-signals.phpt +++ b/sapi/fpm/tests/bug76601-reload-child-signals.phpt @@ -63,18 +63,10 @@ for ($interval = 0; $interval < $max_interval; $interval += $step) { echo "Reached interval $interval us with $step us steps\n"; $tester->expectLogNotice('Reloading in progress ...'); /* Consume mix of 'Reloading in progress ...' and 'reloading: .*' */ -$skipped = $tester->getLogLines(2000); +$tester->readAllLogNotices('Reloading in progress ...'); -$tester->signal('USR2'); -$tester->expectLogNotice('Reloading in progress ...'); -/* When a child ignores SIGQUIT, the following expectation fails due to timeout. */ -if (!$tester->expectLogNotice('reloading: .*')) { - /* for troubleshooting */ - echo "Skipped messages\n"; - echo implode('', $skipped); -} -$tester->expectLogNotice('using inherited socket fd=\d+, "127.0.0.1:\d+"'); -$tester->expectLogStartNotices(); +$tester->reload(); +$tester->expectLogReloadingNotices(); $tester->terminate(); $tester->expectLogTerminatingNotices(); diff --git a/sapi/fpm/tests/gh8885-stderr-fd-reload-usr1.phpt b/sapi/fpm/tests/gh8885-stderr-fd-reload-usr1.phpt index 4ff8d0660936e..fcdaccf40d873 100644 --- a/sapi/fpm/tests/gh8885-stderr-fd-reload-usr1.phpt +++ b/sapi/fpm/tests/gh8885-stderr-fd-reload-usr1.phpt @@ -1,5 +1,5 @@ --TEST-- -FPM: GH-8885 - access.log with stderr begins to write logs to error_log after daemon reload +FPM: GH-8885 - access.log with stderr begins to write logs to error_log after reloading logs --SKIPIF-- true]); -// getPrefixedFile('err.log') is the same path that returns processTemplate('{{FILE:LOG}}') -$errorLogFile = $tester->getPrefixedFile('err.log'); - -$tester->start(); -$tester->expectNoLogMessages(); - -$content = file_get_contents($errorLogFile); -assert($content !== false && strlen($content) > 0, 'File must not be empty'); - -$errorLogLines = explode("\n", $content); -array_pop($errorLogLines); - -assert(count($errorLogLines) === 2, 'Expected 2 records in the error_log file'); -assert(strpos($errorLogLines[0], 'NOTICE: fpm is running, pid')); -assert(strpos($errorLogLines[1], 'NOTICE: ready to handle connections')); - -$tester->ping('{{ADDR}}'); -$stderrLines = $tester->getLogLines(-1); -assert(count($stderrLines) === 1, 'Expected 1 record in the stderr output (access.log)'); -$stderrLine = $stderrLines[0]; -assert(preg_match('/127.0.0.1 .* "GET \/ping" 200$/', $stderrLine), 'Incorrect format of access.log record'); - -$tester->signal('USR1'); +$tester = new FPM\Tester($cfg); +$tester->start(forceStderr: false); $tester->expectNoLogMessages(); - -$content = file_get_contents($errorLogFile); -assert($content !== false && strlen($content) > 0, 'File must not be empty'); -$errorLogLines = explode("\n", $content); -array_pop($errorLogLines); - -assert(count($errorLogLines) >= 4, 'Expected at least 4 records in the error_log file'); -assert(strpos($errorLogLines[0], 'NOTICE: fpm is running, pid')); -assert(strpos($errorLogLines[1], 'NOTICE: ready to handle connections')); -assert(strpos($errorLogLines[2], 'NOTICE: error log file re-opened')); -assert(strpos($errorLogLines[3], 'NOTICE: access log file re-opened')); - - -$tester->ping('{{ADDR}}'); -$stderrLines = $tester->getLogLines(-1); -assert(count($stderrLines) === 1, 'Must be only 1 record in the access.log'); -assert(preg_match('/127.0.0.1 .* "GET \/ping" 200$/', $stderrLines[0]), 'Incorrect format of access.log record'); - +$tester->switchLogSource('{{FILE:LOG}}'); +$tester->expectLogStartNotices(); +$tester->ping(); +$tester->switchLogSource('{{MASTER:OUT}}'); +$tester->expectLogPattern('/127.0.0.1 .* "GET \/ping" 200/'); +$tester->reloadLogs(); +$tester->switchLogSource('{{FILE:LOG}}'); +$tester->expectLogReloadingLogsNotices(); +$tester->ping(); +$tester->switchLogSource('{{MASTER:OUT}}'); +$tester->expectLogPattern('/127.0.0.1 .* "GET \/ping" 200/'); +$tester->switchLogSource('{{FILE:LOG}}'); $tester->terminate(); -$stderrLines = $tester->expectNoLogMessages(); - -$content = file_get_contents($errorLogFile); -assert($content !== false && strlen($content) > 0, 'File must not be empty'); -$errorLogLines = explode("\n", $content); -array_pop($errorLogLines); -$errorLogLastLine = array_pop($errorLogLines); -assert(strpos($errorLogLastLine, 'NOTICE: exiting, bye-bye')); - +$tester->expectLogTerminatingNotices(); +$tester->switchLogSource('{{MASTER:OUT}}'); +$tester->expectNoLogMessages(); $tester->close(); ?> Done diff --git a/sapi/fpm/tests/gh8885-stderr-fd-reload-usr2.phpt b/sapi/fpm/tests/gh8885-stderr-fd-reload-usr2.phpt index 68d9f6fa68b64..e4531d56186df 100644 --- a/sapi/fpm/tests/gh8885-stderr-fd-reload-usr2.phpt +++ b/sapi/fpm/tests/gh8885-stderr-fd-reload-usr2.phpt @@ -26,60 +26,25 @@ pm.min_spare_servers = 1 pm.max_spare_servers = 3 EOT; -// php-fpm must not be launched with --force-stderr option -$tester = new FPM\Tester($cfg, '', [FPM\Tester::PHP_FPM_DISABLE_FORCE_STDERR => true]); -// getPrefixedFile('err.log') is the same path that returns processTemplate('{{FILE:LOG}}') -$errorLogFile = $tester->getPrefixedFile('err.log'); - -$tester->start(); +$tester = new FPM\Tester($cfg); +$tester->start(forceStderr: false); $tester->expectNoLogMessages(); - -$content = file_get_contents($errorLogFile); -assert($content !== false && strlen($content) > 0, 'File must not be empty'); - -$errorLogLines = explode("\n", $content); -array_pop($errorLogLines); - -assert(count($errorLogLines) === 2, 'Expected 2 records in the error_log file'); -assert(strpos($errorLogLines[0], 'NOTICE: fpm is running, pid')); -assert(strpos($errorLogLines[1], 'NOTICE: ready to handle connections')); - -$tester->ping('{{ADDR}}'); -$stderrLines = $tester->getLogLines(-1); -assert(count($stderrLines) === 1, 'Expected 1 record in the stderr output (access.log)'); -$stderrLine = $stderrLines[0]; -assert(preg_match('/127.0.0.1 .* "GET \/ping" 200$/', $stderrLine), 'Incorrect format of access.log record'); - -$tester->signal('USR2'); -$tester->expectLogNotice('using inherited socket fd=\d+, "127.0.0.1:\d+"'); - -$content = file_get_contents($errorLogFile); -assert($content !== false && strlen($content) > 0, 'File must not be empty'); -$errorLogLines = explode("\n", $content); -array_pop($errorLogLines); - -assert(count($errorLogLines) >= 5, 'Expected at least 5 records in the error_log file'); -assert(strpos($errorLogLines[0], 'NOTICE: fpm is running, pid')); -assert(strpos($errorLogLines[1], 'NOTICE: ready to handle connections')); -assert(strpos($errorLogLines[2], 'NOTICE: Reloading in progress')); -assert(strpos($errorLogLines[3], 'NOTICE: reloading: execvp')); -assert(strpos($errorLogLines[4], 'NOTICE: using inherited socket')); - -$tester->ping('{{ADDR}}'); -$stderrLines = $tester->getLogLines(-1); -assert(count($stderrLines) === 1, 'Must be only 1 record in the access.log'); -assert(preg_match('/127.0.0.1 .* "GET \/ping" 200$/', $stderrLines[0]), 'Incorrect format of access.log record'); - +$tester->switchLogSource('{{FILE:LOG}}'); +$tester->expectLogStartNotices(); +$tester->ping(); +$tester->switchLogSource('{{MASTER:OUT}}'); +$tester->expectLogPattern('/127.0.0.1 .* "GET \/ping" 200/'); +$tester->reload(); +$tester->switchLogSource('{{FILE:LOG}}'); +$tester->expectLogReloadingNotices(); +$tester->ping(); +$tester->switchLogSource('{{MASTER:OUT}}'); +$tester->expectLogPattern('/127.0.0.1 .* "GET \/ping" 200/'); +$tester->switchLogSource('{{FILE:LOG}}'); $tester->terminate(); -$stderrLines = $tester->expectNoLogMessages(); - -$content = file_get_contents($errorLogFile); -assert($content !== false && strlen($content) > 0, 'File must not be empty'); -$errorLogLines = explode("\n", $content); -array_pop($errorLogLines); -$errorLogLastLine = array_pop($errorLogLines); -assert(strpos($errorLogLastLine, 'NOTICE: exiting, bye-bye')); - +$tester->expectLogTerminatingNotices(); +$tester->switchLogSource('{{MASTER:OUT}}'); +$tester->expectNoLogMessages(); $tester->close(); ?> Done diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-fallback.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-fallback.phpt index 01b00d44853b4..5d996ddaecee7 100644 --- a/sapi/fpm/tests/log-bwp-msg-flush-split-fallback.phpt +++ b/sapi/fpm/tests/log-bwp-msg-flush-split-fallback.phpt @@ -30,9 +30,8 @@ $tester = new FPM\Tester($cfg, $code); $tester->start(); $tester->expectLogStartNotices(); $tester->request()->expectEmptyBody(); -$lines = $tester->getLogLines(2); -var_dump($lines[0] === str_repeat('a', 1021) . "\0f\n"); -var_dump($lines[1] === "abc\n"); +$tester->expectLogLine(str_repeat('a', 1021) . "\0f", decorated: false); +$tester->expectLogLine("abc", decorated: false); $tester->terminate(); $tester->expectLogTerminatingNotices(); $tester->close(); @@ -40,8 +39,6 @@ $tester->close(); ?> Done --EXPECT-- -bool(true) -bool(true) Done --CLEAN-- start(); $tester->expectLogStartNotices(); $tester->request()->expectEmptyBody(); $tester->terminate(); -var_dump($tester->getLastLogLine() === str_repeat('a', 1022) . "\n"); +$tester->expectLogLine(str_repeat('a', 1022), decorated: false); $tester->close(); ?> Done --EXPECT-- -bool(true) Done --CLEAN-- start(); $tester->expectLogStartNotices(); $tester->request()->expectEmptyBody(); $tester->terminate(); -var_dump($tester->getLastLogLine() === str_repeat('a', 100) . str_repeat('b', 923) . "\n"); -var_dump($tester->getLastLogLine() === str_repeat('b', 1023) . "\n"); -var_dump($tester->getLastLogLine() === str_repeat('b', 554) . "\n"); +$tester->expectLogLine(str_repeat('a', 100) . str_repeat('b', 923), decorated: false); +$tester->expectLogLine(str_repeat('b', 1023), decorated: false); +$tester->expectLogLine(str_repeat('b', 554), decorated: false); $tester->close(); ?> Done --EXPECT-- -bool(true) -bool(true) -bool(true) Done --CLEAN-- debug = $debug; + } + + /** + * Returns log descriptor source. + * + * @return LogSource + * @throws \Exception + */ + private function getSource(): LogSource + { + if ( ! $this->currentSourceName) { + throw new \Exception('Log descriptor is not set'); + } + + return $this->sources[$this->currentSourceName]; + } + + /** + * Set current stream source and create it if it does not exist. + * + * @param string $name Stream name. + * @param resource $stream The actual stream. + */ + public function setStreamSource(string $name, $stream) + { + $this->currentSourceName = $name; + if ( ! isset($this->sources[$name])) { + $this->sources[$name] = new LogStreamSource($stream); + } + } + + /** + * Set file source as current and create it if it does not exist. + * + * @param string $name Source name. + * @param string $filePath Source file path.s + */ + public function setFileSource(string $name, string $filePath) + { + $this->currentSourceName = $name; + if ( ! isset($this->sources[$name])) { + $this->sources[$name] = new LogFileSource($filePath); + } + } + + /** + * Get a single log line. + * + * @param int $timeoutSeconds + * @param int $timeoutMicroseconds + * + * @return null|string + * @throws \Exception + */ + public function getLine(int $timeoutSeconds = 3, int $timeoutMicroseconds = 0): ?string + { + $line = $this->getSource()->getLine($timeoutSeconds, $timeoutMicroseconds); + $this->trace(is_null($line) ? "LINE - null" : "LINE: $line"); + + return $line; + } + + /** + * Print separation line. + */ + public function printSeparator(): void + { + echo str_repeat('-', 68) . "\n"; + } + + /** + * Print all logs. + */ + public function printLogs(): void + { + $hasMultipleDescriptors = count($this->sources) > 1; + echo "LOGS:\n"; + foreach ($this->sources as $name => $source) { + if ($hasMultipleDescriptors) { + echo ">>> source: $name\n"; + } + $this->printSeparator(); + foreach ($source->getAllLines() as $line) { + echo $line; + } + $this->printSeparator(); + } + } + + /** + * Print error and logs. + * + * @param string|null $errorMessage Error message to print before the logs. + * + * @return false + */ + private function printError(?string $errorMessage): bool + { + if (is_null($errorMessage)) { + return false; + } + echo "ERROR: " . $errorMessage . "\n\n"; + $this->printLogs(); + echo "\n"; + + return false; + } + + /** + * Read log until matcher matches the log message or there are no more logs. + * + * @param callable $matcher Callback to identify a match + * @param string|null $notFoundMessage Error message if matcher does not succeed. + * @param bool $checkAllLogs Whether to also check past logs. + * @param int $timeoutSeconds Timeout in seconds for reading of all messages. + * @param int $timeoutMicroseconds Additional timeout in microseconds for reading of all messages. + * + * @return bool + * @throws \Exception + */ + public function readUntil( + callable $matcher, + string $notFoundMessage = null, + bool $checkAllLogs = false, + int $timeoutSeconds = 3, + int $timeoutMicroseconds = 0 + ): bool { + $startTime = microtime(true); + $endTime = $startTime + $timeoutSeconds + ($timeoutMicroseconds / 1_000_000); + if ($checkAllLogs) { + foreach ($this->getSource()->getAllLines() as $line) { + if ($matcher($line)) { + return true; + } + } + } + + do { + if (microtime(true) > $endTime) { + return $this->printError($notFoundMessage); + } + $line = $this->getLine($timeoutSeconds, $timeoutMicroseconds); + if ($line === null || microtime(true) > $endTime) { + return $this->printError($notFoundMessage); + } + } while ( ! $matcher($line)); + + return true; + } + + /** + * Print tracing message - only in debug . + * + * @param string $msg Message to print. + */ + private function trace(string $msg): void + { + if ($this->debug) { + print "LogReader - $msg"; + } + } +} + +abstract class LogSource +{ + /** + * Get single line from the source. + * + * @param int $timeoutSeconds Read timeout in seconds + * @param int $timeoutMicroseconds Read timeout in microseconds + * + * @return string|null + */ + public abstract function getLine(int $timeoutSeconds, int $timeoutMicroseconds): ?string; + + /** + * Get all lines that has been returned by getLine() method. + * + * @return string[] + */ + public abstract function getAllLines(): array; +} + +class LogStreamSource extends LogSource +{ + /** + * @var resource + */ + private $stream; + + /** + * @var array + */ + private array $lines = []; + + public function __construct($stream) + { + $this->stream = $stream; + } + + /** + * Get single line from the stream. + * + * @param int $timeoutSeconds Read timeout in seconds + * @param int $timeoutMicroseconds Read timeout in microseconds + * + * @return string|null + */ + public function getLine(int $timeoutSeconds, int $timeoutMicroseconds): ?string + { + if (feof($this->stream)) { + return null; + } + $read = [$this->stream]; + $write = null; + $except = null; + if (stream_select($read, $write, $except, $timeoutSeconds, $timeoutMicroseconds)) { + $line = fgets($this->stream); + $this->lines[] = $line; + + return $line; + } else { + return null; + } + } + + /** + * Get all stream read lines. + * + * @return string[] + */ + public function getAllLines(): array + { + return $this->lines; + } +} + +class LogFileSource extends LogSource +{ + /** + * @var string + */ + private string $filePath; + + /** + * @var int + */ + private int $position; + + /** + * @var array + */ + private array $lines = []; + + public function __construct(string $filePath) + { + $this->filePath = $filePath; + $this->position = 0; + } + + /** + * Get single line from the file. + * + * @param int $timeoutSeconds Read timeout in seconds + * @param int $timeoutMicroseconds Read timeout in microseconds + * + * @return string|null + */ + public function getLine(int $timeoutSeconds, int $timeoutMicroseconds): ?string + { + $endTime = microtime(true) + $timeoutSeconds + ($timeoutMicroseconds / 1_000_000); + while ($this->position >= count($this->lines)) { + if (is_file($this->filePath)) { + $lines = file($this->filePath); + if ($lines === false) { + return null; + } + $this->lines = $lines; + if ($this->position < count($lines)) { + break; + } + } + usleep(50_000); + if (microtime(true) > $endTime) { + return null; + } + } + + return $this->lines[$this->position++]; + } + + /** + * Get all returned lines from the file. + * + * @return string[] + */ + public function getAllLines(): array + { + return array_slice($this->lines, 0, $this->position); + } +} diff --git a/sapi/fpm/tests/logtool.inc b/sapi/fpm/tests/logtool.inc index e085ae291beab..b1c9009f6f84a 100644 --- a/sapi/fpm/tests/logtool.inc +++ b/sapi/fpm/tests/logtool.inc @@ -4,7 +4,8 @@ namespace FPM; class LogTool { - const P_TIME = '\[\d\d-\w\w\w-\d{4} \d\d:\d\d:\d\d\]'; + const P_TIME = '\[\d\d-\w\w\w-\d{4} \d\d:\d\d:\d\d(?:\.\d+)?\]'; + const P_DEBUG = '(?:pid \d+, (?:\w+|\(null\))\(\), line \d+: )?'; const P_PREFIX = '\[pool unconfined\] child \d+ said into stderr: '; const P_PREFIX_STDOUT = '\[pool unconfined\] child \d+ said into stdout: '; const FINAL_SUFFIX = ', pipe is closed'; @@ -16,67 +17,96 @@ class LogTool const ALERT = 'ALERT'; /** - * @var string + * @var bool + */ + private bool $debug; + + /** + * @var LogReader */ - private $message; + private LogReader $logReader; /** * @var string */ - private $level; + private string $message; + + /** + * @var string|null + */ + private ?string $level = null; /** * @var int */ - private $position; + private int $position; /** * @var int */ - private $suffixPosition; + private int $suffixPosition = 0; /** * @var int */ - private $limit; + private int $limit; /** - * @var string + * @var string|null */ - private $pattern; + private ?string $pattern; /** - * @var string + * @var string|null */ - private $error; + private ?string $error = null; /** * @var bool */ - private $pipeClosed = false; + private bool $pipeClosed = false; /** + * Log tool constructor. + * + * @param LogReader $logReader + * @param bool $debug + */ + public function __construct(LogReader $logReader, bool $debug = false) + { + $this->logReader = $logReader; + $this->debug = $debug; + } + + /** + * Set expected message for output logging. + * * @param string $message - * @param int $limit - * @param int $repeat + * @param int $limit + * @param int $repeat */ public function setExpectedMessage(string $message, int $limit, int $repeat = 0) { - $this->message = ($repeat > 0) ? str_repeat($message, $repeat) : $message; - $this->limit = $limit; + $this->message = ($repeat > 0) ? str_repeat($message, $repeat) : $message; + $this->limit = $limit; $this->position = 0; } /** + * Set the expected logging level. + * * @param string $level - * @return int + * + * @return string */ - public function setExpectedLevel(string $level) + public function setExpectedLevel(string $level): string { return $this->level = $level; } /** + * Get the expected logging level. + * * @return string */ public function getExpectedLevel(): string @@ -85,172 +115,239 @@ class LogTool } /** + * Set whether pipe closed error is shown. + * * @param bool $pipeClosed */ - public function setPipeClosed(bool $pipeClosed) + public function setPipeClosed(bool $pipeClosed): void { $this->pipeClosed = $pipeClosed; } /** - * @param string $line + * Match the matcher checking the log lines using the callback. + * + * @param callable $matcher Callback checking whether the log line matches the expected message. + * @param string $notFoundMessage Error message to show if the message is not found. + * * @return bool + * @throws \Exception */ - public function checkTruncatedMessage(string $line) + private function match(callable $matcher, string $notFoundMessage): bool { - if ($this->message === null) { - throw new \LogicException('The message has not been set'); - } - $lineLen = strlen($line); - if (!$this->checkLineLength($line)) { + if ($this->getError()) { return false; } - $this->pattern = '/^PHP message: (.*?)(\.\.\.)?$/'; - if (preg_match($this->pattern, $line, $matches) === 0) { - return $this->error("Unexpected truncated message: {$line}"); + + if ($this->logReader->readUntil($matcher, $notFoundMessage)) { + $this->popError(); + + return true; } + echo $this->popError(); - if ($lineLen === $this->limit - strlen('NOTICE: ') - 1) { - if (!isset($matches[2])) { - return $this->error("The truncated line is not ended with '...'"); - } - if (!$this->checkMessage($matches[1])) { + return false; + } + + /** + * @param string|null $line Log line to check against. + * + * @return bool + * @throws \Exception + */ + public function checkTruncatedMessage(string $line = null): bool + { + if ($this->message === null) { + throw new \LogicException('The message has not been set'); + } + + $matcher = function (string $line) { + $lineLen = strlen($line); + if ( ! $this->checkLineLength($line)) { return false; } - } else { - if (isset($matches[2])) { - // this is expecting that the expected message does not end with '...' - // which should not be an issue for the test purpose. - return $this->error("The line is complete and should not end with '...'"); + $this->pattern = '/^PHP message: (.*?)(\.\.\.)?$/'; + if (preg_match($this->pattern, $line, $matches) === 0) { + return $this->error("Unexpected truncated message: {$line}"); } - if (!$this->checkMessage($matches[1], -1)) { - return false; + + if ($lineLen === $this->limit - strlen('NOTICE: ') - 1) { + if ( ! isset($matches[2])) { + return $this->error("The truncated line is not ended with '...'"); + } + if ( ! $this->checkMessage($matches[1])) { + return false; + } + } else { + if (isset($matches[2])) { + // this is expecting that the expected message does not end with '...' + // which should not be an issue for the test purpose. + return $this->error("The line is complete and should not end with '...'"); + } + if ( ! $this->checkMessage($matches[1], -1)) { + return false; + } } - } - return true; + return true; + }; + + if ($line !== null) { + return $matcher($line); + } else { + return $this->match($matcher, 'Truncated message not found'); + } } /** - * @param array $lines - * @param bool $terminated - * @param bool $decorated + * Check wrapped message. + * + * @param bool $terminated Whether to check termination lines. + * @param bool $decorated Whether the output is decorated with prefix and suffix. + * @param bool $isStdErr Whether the message is written to stderr. + * * @return bool + * @throws \Exception */ - public function checkWrappedMessage(array $lines, bool $terminated = true, bool $decorated = true, bool $is_stderr = true) - { + public function checkWrappedMessage( + bool $terminated = true, + bool $decorated = true, + bool $isStdErr = true, + ): bool { if ($this->message === null) { throw new \LogicException('The message has not been set'); } if ($decorated) { $this->pattern = sprintf( - '/^(%s %s: %s)"([^"]*)"(.*)?$/', + '/^(%s %s: %s%s)"([^"]*)"(.*)?$/', self::P_TIME, $this->getExpectedLevel(), - $is_stderr ? self::P_PREFIX : self::P_PREFIX_STDOUT + self::P_DEBUG, + $isStdErr ? self::P_PREFIX : self::P_PREFIX_STDOUT ); } else { $this->pattern = null; } - $idx = 0; - foreach ($lines as $idx => $line) { - if (!$this->checkLine($line)) { - break; + $matcher = fn(string $line) => $this->checkLine($line); + + while (strlen($this->message) !== $this->position) { + if ( ! $this->match($matcher, 'Output message not found')) { + return false; } } if ($this->suffixPosition > 0) { - $suffixPattern = sprintf( - '/^%s %s: %s(.*)$/', - self::P_TIME, $this->getExpectedLevel(), - $is_stderr ? self::P_PREFIX : self::P_PREFIX_STDOUT - ); - $line = $lines[++$idx]; - if (preg_match($suffixPattern, $line, $matches) === 0) { - return $this->error("Unexpected line: $line"); - } - if ($matches[1] !== substr(self::FINAL_SUFFIX, $this->suffixPosition)) { - return $this->error( - "The suffix has not been finished from position $this->suffixPosition in line: $line" + $suffixMatcher = function ($line) use ($isStdErr) { + $suffixPattern = sprintf( + '/^%s %s: %s%s(.*)$/', + self::P_TIME, + $this->getExpectedLevel(), + self::P_DEBUG, + $isStdErr ? self::P_PREFIX : self::P_PREFIX_STDOUT ); + if (preg_match($suffixPattern, $line, $matches) === 0) { + return $this->error("Unexpected line: $line"); + } + if ($matches[1] !== substr(self::FINAL_SUFFIX, $this->suffixPosition)) { + return $this->error( + "The suffix has not been finished from position $this->suffixPosition in line: $line" + ); + } + + return true; + }; + if ( ! $this->match($suffixMatcher, 'Suffix message not found')) { + return false; } + $this->suffixPosition = 0; } if ($terminated) { - return $this->expectTerminatorLines($lines, $idx); + return $this->expectTerminatorLines(); } return true; } /** - * @param string $line + * Check workers output line. + * + * @param string $line Log output line. + * * @return bool */ - private function checkLine(string $line) + private function checkLine(string $line): bool { - if ($this->pattern === null) { + $useLine = $this->pattern === null; + if ($useLine) { // plain (not decorated) output - $out = rtrim($line); + $out = rtrim($line); $finalSuffix = null; - } elseif (($res = preg_match($this->pattern, $line, $matches)) > 0) { - $out = $matches[2]; + } elseif (preg_match($this->pattern, $line, $matches) > 0) { + $out = $matches[2]; $finalSuffix = $matches[3] ?? false; } else { - return $this->error("Unexpected line: $line"); + return $this->error("Unexpected line: $line", $line); } - $rem = strlen($this->message) - $this->position; + $rem = strlen($this->message) - $this->position; $lineLen = strlen($line); - if (!$this->checkLineLength($line, $lineLen)) { + if ( ! $this->checkLineLength($line, $lineLen)) { return false; } - if (!$this->checkMessage($out, $this->position)) { + if ( ! $this->checkMessage($out, $this->position, $useLine)) { return false; } - $outLen = strlen($out); + $outLen = strlen($out); + $this->position += $outLen; if ($rem > $outLen) { // continuous line if ($lineLen !== $this->limit) { if ($lineLen + ($rem - $outLen) < $this->limit) { return $this->error("Printed less than the message len"); } + return $this->error( "The continuous line length is $lineLen but it should equal to limit $this->limit" ); } - $this->position += $outLen; + return true; } - if ($rem !== $outLen) { + if ($rem !== $outLen) { return $this->error("Printed more than the message len"); } - if (!$this->pipeClosed || $finalSuffix === null) { - return false; + if ( ! $this->pipeClosed || $finalSuffix === null) { + return true; } if ($finalSuffix === false) { return $this->error("No final suffix"); } - if (empty($finalSuffix) || strpos(self::FINAL_SUFFIX, $finalSuffix) === false) { + if (empty($finalSuffix) || ! str_contains(self::FINAL_SUFFIX, $finalSuffix)) { return $this->error("The final suffix has to be equal to ', pipe is closed'"); } if (self::FINAL_SUFFIX !== $finalSuffix) { $this->suffixPosition = strlen($finalSuffix); } - // complete final suffix printed - return false; + + return true; } /** - * @param string $line - * @param int $lineLen + * Check the message line length - specifically if it's behind the limit. + * + * @param string $line Log output line. + * @param int|null $lineLen Line length. + * * @return bool */ - private function checkLineLength(string $line, $lineLen = null) { + private function checkLineLength(string $line, int $lineLen = null): bool + { $lineLen = $lineLen ?: strlen($line); if ($lineLen > $this->limit) { return $this->error( - "The line length is $lineLen which is higher than limit $this->limit" + "The line length is $lineLen which is higher than limit $this->limit", + $line ); } @@ -258,12 +355,19 @@ class LogTool } /** - * @param string $matchedMessage - * @param int $expectedMessageStart + * Check whether matched message part matches the expected message. + * + * @param string $matchedMessage The output message or part of it (match). + * @param int $expectedMessageStart Message position. + * @param bool $isLine Whether the whole log line is provided as a matched message. + * * @return bool */ - private function checkMessage(string $matchedMessage, int $expectedMessageStart = 0) - { + private function checkMessage( + string $matchedMessage, + int $expectedMessageStart = 0, + bool $isLine = false + ): bool { if ($expectedMessageStart < 0) { $expectedMessage = $this->message; } else { @@ -271,247 +375,430 @@ class LogTool } if ($expectedMessage !== $matchedMessage) { return $this->error( - sprintf( - "The actual string(%d) does not match expected string(%d):\n", - strlen($matchedMessage), - strlen($expectedMessage) - ) . - "- EXPECT: '$expectedMessage'\n" . - "- ACTUAL: '$matchedMessage'" + $this->getMatchDebugMessage( + sprintf( + "The actual string(%d) does not match expected string(%d):\n", + strlen($matchedMessage), + strlen($expectedMessage) + ), + expectedMessage: $expectedMessage, + actualMessage: "'$matchedMessage'", + ), + $isLine ? $matchedMessage : null ); } + $this->traceMatch( + "Message matched", + expectedMessage: $expectedMessage, + actualMessage: "'$matchedMessage'", + ); + return true; } /** - * @param array $lines + * Expect log entries for daemon reloading. + * + * @param int $expectedNumberOfSockets + * @param bool $expectInitialProgressMessage + * @param bool $expectReloadingMessage + * * @return bool + * @throws \Exception */ - public function expectReloadingLines(array $lines) - { - if ( - !$this->expectNotice($lines[0], 'Reloading in progress ...') || - !$this->expectNotice($lines[1], 'reloading: .*') - ) { + public function expectReloadingLines( + int $expectedNumberOfSockets, + bool $expectInitialProgressMessage = true, + bool $expectReloadingMessage = true + ): bool { + if ($expectInitialProgressMessage && ! $this->expectNotice('Reloading in progress ...')) { + return false; + } + if ($expectReloadingMessage && ! $this->expectNotice('reloading: .*')) { return false; } - for ($i = 2; $i < count($lines) - 2; $i++) { - if (!$this->expectNotice($lines[$i], 'using inherited socket fd=\d+, "[^"]+"')) { + for ($i = 0; $i < $expectedNumberOfSockets; $i++) { + if ( ! $this->expectNotice('using inherited socket fd=\d+, "[^"]+"')) { return false; } } - return $this->expectStartingLines(array_splice($lines, $i)); + return $this->expectStartingLines(); + } + + /** + * Expect log entries for reloading logs. + * + * @return bool + * @throws \Exception + */ + public function expectReloadingLogsLines(): bool { + return ( + $this->expectNotice('error log file re-opened') && + $this->expectNotice('access log file re-opened') + ); } /** - * @param array $lines + * Expect starting lines when FPM starts. + * * @return bool + * @throws \Exception */ - public function expectStartingLines(array $lines) + public function expectStartingLines(): bool { if ($this->getError()) { return false; } - if (count($lines) < 2) { - return $this->error("No starting lines"); - } - return ( - $this->expectNotice($lines[0], 'fpm is running, pid \d+') && - $this->expectNotice($lines[1], 'ready to handle connections') + $this->expectNotice('fpm is running, pid \d+') && + $this->expectNotice('ready to handle connections') ); } /** - * @param array $lines - * @param int $idx + * Expect termination lines when FPM terminates. + * * @return bool + * @throws \Exception */ - public function expectTerminatorLines(array $lines, int $idx = -1) + public function expectTerminatorLines(): bool { if ($this->getError()) { return false; } - if (count($lines) - $idx < 3) { - return $this->error("No terminating lines"); - } - return ( - $this->expectNotice($lines[++$idx], 'Terminating ...') && - $this->expectNotice($lines[++$idx], 'exiting, bye-bye!') + $this->expectNotice('Terminating ...') && + $this->expectNotice('exiting, bye-bye!') ); } /** - * @param string $type - * @param string $line - * @param string $expectedMessage - * @param string|null $pool + * Get log entry matcher. + * + * @param string $type Entry type like NOTICE, WARNING, DEBUG and so on. + * @param string $expectedMessage Message to search for + * @param string $pool Pool that is used and prefixes the message. + * @param string $ignoreErrorFor Ignore error for supplied string in the message. + * + * @return callable + */ + private function getEntryMatcher( + string $type, + string $expectedMessage, + ?string $pool, + string $ignoreErrorFor + ): callable { + if ($pool !== null) { + $expectedMessage = '\[pool ' . $pool . '\] ' . $expectedMessage; + } + $this->trace("Matching EXPECTED: $expectedMessage"); + + $pattern = sprintf('/^(?:%s )?%s: %s(%s)$/', self::P_TIME, $type, self::P_DEBUG, $expectedMessage); + $this->trace("PATTERN: $pattern"); + + return function ($line) use ($expectedMessage, $pattern, $type, $ignoreErrorFor) { + $line = rtrim($line); + if (preg_match($pattern, $line, $matches) === 0) { + if ($this->getError()) { // quick bail out to save some CPU + return false; + } + + // get actual message + $types = implode('|', [self::NOTICE, self::WARNING, self::ERROR, self::ALERT]); + $errorPattern = sprintf('/^(?:%s )?(%s): %s(.*)$/', self::P_TIME, $types, self::P_DEBUG); + if (preg_match($errorPattern, $line, $matches) === 0) { + $actualMessage = null; + } else { + $expectedMessage = $type . ' - ' . $expectedMessage; + $actualMessage = $matches[1] . ' - ' . $matches[2]; + } + + return $this->error( + $this->getMatchDebugMessage( + 'Most likely invalid match for entry', + $pattern, + $line, + $expectedMessage, + $actualMessage + ), + $line, + $ignoreErrorFor + ); + } + $this->trace("Matched ACTUAL: " . $matches[1]); + + return true; + }; + } + + /** + * Read all log entries until timeout. + * + * @param string $type Entry type like NOTICE, WARNING, DEBUG and so on. + * @param string $expectedMessage Message to search for + * @param string|null $pool Pool that is used and prefixes the message. + * @param string $ignoreErrorFor Ignore error for supplied string in the message. + * * @return bool + * @throws \Exception */ - public function expectEntry(string $type, string $line, string $expectedMessage, $pool = null) - { + public function readAllEntries( + string $type, + string $expectedMessage, + string $pool = null, + string $ignoreErrorFor = self::DEBUG + ): bool { if ($this->getError()) { return false; } - if ($pool !== null) { - $expectedMessage = '\[pool ' . $pool . '\] ' . $expectedMessage; - } - $line = rtrim($line); - $pattern = sprintf('/^(%s )?%s: %s$/', self::P_TIME, $type, $expectedMessage); + $matcher = $this->getEntryMatcher($type, $expectedMessage, $pool, $ignoreErrorFor); - if (preg_match($pattern, $line, $matches) === 0) { - return $this->error( - "The $type does not match expected message:\n" . - "- PATTERN: $pattern\n" . - "- MESSAGE: $line\n" . - "- EXPECT: '$expectedMessage'\n" . - "- ACTUAL: '" . substr($line, strpos($line, $type) + strlen($type) + 2) . "'" - ); + while ($this->logReader->readUntil($matcher)) { + $this->popError(); } + $this->popError(); return true; } /** - * @param string $line - * @param string $expectedMessage + * Expect log entry. + * + * @param string $type Entry type like NOTICE, WARNING, DEBUG and so on. + * @param string $expectedMessage Message to search for + * @param string|null $pool Pool that is used and prefixes the message. + * @param string $ignoreErrorFor Ignore error for supplied string in the message. + * + * @return bool + * @throws \Exception + */ + public function expectEntry( + string $type, + string $expectedMessage, + string $pool = null, + string $ignoreErrorFor = self::DEBUG + ): bool { + if ($this->getError()) { + return false; + } + + return $this->match( + $this->getEntryMatcher($type, $expectedMessage, $pool, $ignoreErrorFor), + "The $type does not match expected message" + ); + } + + /** + * Expect debug log entry. + * + * @param string $expectedMessage * @param string|null $pool + * * @return bool + * @throws \Exception */ - public function expectDebug(string $line, string $expectedMessage, $pool = null) + public function expectDebug(string $expectedMessage, string $pool = null): bool { - return $this->expectEntry(self::DEBUG, $line, $expectedMessage, $pool); + return $this->expectEntry(self::DEBUG, $expectedMessage, $pool, self::ERROR); } /** - * @param string $line - * @param string $expectedMessage + * Expect notice log entry. + * + * @param string $expectedMessage * @param string|null $pool + * * @return bool + * @throws \Exception */ - public function expectNotice(string $line, string $expectedMessage, $pool = null) + public function expectNotice(string $expectedMessage, string $pool = null): bool { - return $this->expectEntry(self::NOTICE, $line, $expectedMessage, $pool); + return $this->expectEntry(self::NOTICE, $expectedMessage, $pool); } /** - * @param string $line - * @param string $expectedMessage + * Expect warning log entry. + * + * @param string $expectedMessage * @param string|null $pool + * * @return bool + * @throws \Exception */ - public function expectWarning(string $line, string $expectedMessage, $pool = null) + public function expectWarning(string $expectedMessage, string $pool = null): bool { - return $this->expectEntry(self::WARNING, $line, $expectedMessage, $pool); + return $this->expectEntry(self::WARNING, $expectedMessage, $pool); } /** - * @param string $line - * @param string $expectedMessage + * Expect error log entry. + * + * @param string $expectedMessage * @param string|null $pool + * * @return bool + * @throws \Exception */ - public function expectError(string $line, string $expectedMessage, $pool = null) + public function expectError(string $expectedMessage, string $pool = null): bool { - return $this->expectEntry(self::ERROR, $line, $expectedMessage, $pool); + return $this->expectEntry(self::ERROR, $expectedMessage, $pool); } /** - * @param string $line - * @param string $expectedMessage + * Expect alert log entry. + * + * @param string $expectedMessage * @param string|null $pool + * * @return bool + * @throws \Exception */ - public function expectAlert(string $line, string $expectedMessage, $pool = null) + public function expectAlert(string $expectedMessage, string $pool = null): bool { - return $this->expectEntry(self::ALERT, $line, $expectedMessage, $pool); + return $this->expectEntry(self::ALERT, $expectedMessage, $pool); } /** - * @param string $msg + * Expect pattern in the log line. + * + * @param string $pattern + * * @return bool + * @throws \Exception */ - private function error(string $msg) + public function expectPattern(string $pattern): bool { - $this->error = $msg; - echo "ERROR: $msg\n"; - return false; + return $this->match( + function ($line) use ($pattern) { + if (preg_match($pattern, $line) === 1) { + $this->traceMatch("Pattern expectation", $pattern, $line); + + return true; + } + + return false; + }, + 'The search pattern not found' + ); } /** + * Get match debug message. + * + * @param string $title + * @param string|null $pattern + * @param string|null $line + * @param string|null $expectedMessage + * @param string|null $actualMessage + * * @return string */ - public function getError() + private function getMatchDebugMessage( + string $title, + string $pattern = null, + string $line = null, + string $expectedMessage = null, + string $actualMessage = null + ): string { + $msg = "$title:\n"; + if ($pattern !== null) { + $msg .= "- PATTERN: $pattern\n"; + } + if ($line !== null) { + $msg .= "- LINE: $line\n"; + } + if ($expectedMessage !== null) { + $msg .= "- EXPECTED: $expectedMessage\n"; + } + if ($actualMessage !== null) { + $msg .= "- ACTUAL: $actualMessage\n"; + } + + return $msg; + } + + /** + * Print tracing of the match. + * + * @param string $title + * @param string|null $pattern + * @param string|null $line + * @param string|null $expectedMessage + * @param string|null $actualMessage + */ + private function traceMatch( + string $title, + string $pattern = null, + string $line = null, + string $expectedMessage = null, + string $actualMessage = null + ): void { + if ($this->debug) { + echo "LogTool - " . $this->getMatchDebugMessage($title, $pattern, $line, $expectedMessage, $actualMessage); + } + } + + /** + * Print tracing message - only in debug . + * + * @param string $msg Message to print. + */ + private function trace(string $msg): void { - return $this->error; + if ($this->debug) { + print "LogTool - $msg\n"; + } } -} -if (isset($argv[1]) && $argv[1] === 'logtool-selftest') { - $cases = [ - [ - 'limit' => 1050, - 'lines' => [ - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' . - str_repeat('a', 968) . '"', - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' . - str_repeat('a', 968) . '"', - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' . - str_repeat('a', 112) . '", pipe is closed', - '[08-Oct-2017 19:53:55] NOTICE: Terminating ...', - '[08-Oct-2017 19:53:55] NOTICE: exiting, bye-bye!', - ], - 'message' => str_repeat('a', 2048), - 'type' => 'stdio', - ], - [ - 'limit' => 1050, - 'lines' => [ - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' . - str_repeat('a', 968) . '"', - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' . - str_repeat('a', 968) . '"', - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' . - str_repeat('a', 964) . '", pi', - '[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: pe is closed', - '[08-Oct-2017 19:53:55] NOTICE: Terminating ...', - '[08-Oct-2017 19:53:55] NOTICE: exiting, bye-bye!', - ], - 'message' => str_repeat('a', 2900), - 'type' => 'stdio', - ], - [ - 'limit' => 1024, - 'line' => '[08-Oct-2017 19:53:50] WARNING: ' . str_repeat('a',989) . '...', - 'message' => str_repeat('a', 2900), - 'type' => 'message', - ], - [ - 'limit' => 1024, - 'line' => '[08-Oct-2017 19:53:50] WARNING: ' . str_repeat('a',20), - 'message' => str_repeat('a', 20), - 'type' => 'message', - ], - ]; - foreach ($cases as $case) { - printf("Test message with len %d and limit %d: ", strlen($case['message']), $case['limit']); - $logTool = new LogTool(); - $logTool->setExpectedMessage($case['message'], $case['limit']); - if ($case['type'] === 'stdio') { - $logTool->checkWrappedMessage($case['lines']); - } else { - $logTool->checkTruncatedMessage($case['line']); + + /** + * Save error message if the line does not contain ignored string. + * + * @param string $msg + * @param string|null $line + * @param string $ignoreFor + * + * @return false + */ + private function error(string $msg, string $line = null, string $ignoreFor = self::DEBUG): bool + { + if ($this->error === null && ($line === null || ! str_contains($line, $ignoreFor))) { + $this->trace("Setting error: $msg"); + $this->error = $msg; } - if (!$logTool->getError()) { - echo "OK\n"; + + return false; + } + + /** + * Get saved error. + * + * @return string|null + */ + public function getError(): ?string + { + return $this->error; + } + + /** + * Get saved error and clear it. + * + * @return string|null + */ + public function popError(): ?string + { + $error = $this->error; + $this->error = null; + if ($error !== null) { + $this->trace("Clearing error: $error"); } + + return $error; } - echo "Done\n"; } diff --git a/sapi/fpm/tests/response.inc b/sapi/fpm/tests/response.inc index 1d0783b66ec35..9112da6ed7756 100644 --- a/sapi/fpm/tests/response.inc +++ b/sapi/fpm/tests/response.inc @@ -43,25 +43,26 @@ class Response /** * @param string|array|null $data - * @param bool $expectInvalid + * @param bool $expectInvalid */ public function __construct($data = null, $expectInvalid = false) { - if (!is_array($data)) { + if ( ! is_array($data)) { $data = [ - 'response' => $data, + 'response' => $data, 'err_response' => null, 'out_response' => $data, ]; } - $this->data = $data; + $this->data = $data; $this->expectInvalid = $expectInvalid; } /** - * @param mixed $body + * @param mixed $body * @param string $contentType + * * @return Response */ public function expectBody($body, $contentType = 'text/html') @@ -99,11 +100,14 @@ class Response } /** - * @param string $name - * @param string $value + * Expect header in the response. + * + * @param string $name Header name. + * @param string $value Header value. + * * @return Response */ - public function expectHeader($name, $value) + public function expectHeader($name, $value): Response { $this->checkHeader($name, $value); @@ -111,10 +115,13 @@ class Response } /** - * @param string|null $errorMessage + * Expect error in the response. + * + * @param string|null $errorMessage Expected error message. + * * @return Response */ - public function expectError($errorMessage) + public function expectError($errorMessage): Response { $errorData = $this->getErrorData(); if ($errorData !== $errorMessage) { @@ -128,19 +135,23 @@ class Response } /** - * @param string $errorMessage + * Expect no error in the response. + * * @return Response */ - public function expectNoError() + public function expectNoError(): Response { return $this->expectError(null); } /** - * @param string $contentType + * Get response body. + * + * @param string $contentType Expect body to have specified content type. + * * @return string|null */ - public function getBody($contentType = 'text/html') + public function getBody(string $contentType = 'text/html'): ?string { if ($this->checkIfValid() && $this->checkDefaultHeaders($contentType)) { return $this->rawBody; @@ -150,7 +161,7 @@ class Response } /** - * Print raw body + * Print raw body. */ public function dumpBody() { @@ -158,7 +169,7 @@ class Response } /** - * Print raw body + * Print raw body. */ public function printBody() { @@ -170,18 +181,18 @@ class Response */ public function debugOutput() { - echo "-------------- RESPONSE: --------------\n"; - echo "OUT:\n"; - echo $this->data['out_response']; - echo "ERR:\n"; - echo $this->data['err_response']; + echo ">>> Response\n"; + echo "----------------- OUT -----------------\n"; + echo $this->data['out_response'] . "\n"; + echo "----------------- ERR -----------------\n"; + echo $this->data['err_response'] . "\n"; echo "---------------------------------------\n\n"; } /** * @return string|null */ - public function getErrorData() + public function getErrorData(): ?string { return $this->data['err_response']; } @@ -191,13 +202,13 @@ class Response * * @return bool */ - private function checkIfValid() + private function checkIfValid(): bool { if ($this->isValid()) { return true; } - if (!$this->expectInvalid) { + if ( ! $this->expectInvalid) { $this->error("The response is invalid: $this->rawData"); } @@ -205,41 +216,48 @@ class Response } /** + * Check default headers that should be present. + * * @param string $contentType + * * @return bool */ - private function checkDefaultHeaders($contentType) + private function checkDefaultHeaders($contentType): bool { // check default headers return ( - $this->checkHeader('X-Powered-By', '|^PHP/8|', true) && + ( ! ini_get('expose_php') || $this->checkHeader('X-Powered-By', '|^PHP/8|', true)) && $this->checkHeader('Content-type', '|^' . $contentType . '(;\s?charset=\w+)?|', true) ); } /** - * @param string $name - * @param string $value - * @param bool $useRegex + * Check a specified header. + * + * @param string $name Header name. + * @param string $value Header value. + * @param bool $useRegex Whether value is regular expression. + * * @return bool */ - private function checkHeader(string $name, string $value, $useRegex = false) + private function checkHeader(string $name, string $value, $useRegex = false): bool { - $lcName = strtolower($name); + $lcName = strtolower($name); $headers = $this->getHeaders(); - if (!isset($headers[$lcName])) { + if ( ! isset($headers[$lcName])) { return $this->error("The header $name is not present"); } $header = $headers[$lcName]; - if (!$useRegex) { + if ( ! $useRegex) { if ($header === $value) { return true; } + return $this->error("The header $name value '$header' is not the same as '$value'"); } - if (!preg_match($value, $header)) { + if ( ! preg_match($value, $header)) { return $this->error("The header $name value '$header' does not match RegExp '$value'"); } @@ -247,11 +265,13 @@ class Response } /** + * Get all headers. + * * @return array|null */ - private function getHeaders() + private function getHeaders(): ?array { - if (!$this->isValid()) { + if ( ! $this->isValid()) { return null; } @@ -260,7 +280,7 @@ class Response } $headerRows = explode("\r\n", $this->rawHeaders); - $headers = []; + $headers = []; foreach ($headerRows as $headerRow) { $colonPosition = strpos($headerRow, ':'); if ($colonPosition === false) { @@ -292,8 +312,8 @@ class Response private function processData() { $this->rawData = $this->data['out_response']; - $this->valid = ( - !is_null($this->rawData) && + $this->valid = ( + ! is_null($this->rawData) && strpos($this->rawData, self::HEADER_SEPARATOR) ); if ($this->valid) { @@ -308,9 +328,10 @@ class Response * Emit error message * * @param string $message + * * @return bool */ - private function error($message) + private function error($message): bool { echo "ERROR: $message\n"; diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc index 8eaed315779fb..202e2df3d2fde 100644 --- a/sapi/fpm/tests/tester.inc +++ b/sapi/fpm/tests/tester.inc @@ -5,6 +5,7 @@ namespace FPM; use Adoy\FastCGI\Client; require_once 'fcgi.inc'; +require_once 'logreader.inc'; require_once 'logtool.inc'; require_once 'response.inc'; @@ -35,15 +36,10 @@ class Tester */ const FILE_EXT_PID = 'pid'; - /** - * Name for the option to manage php-fpm --force-stderr flag - */ - const PHP_FPM_DISABLE_FORCE_STDERR = 'disable-force-stderr'; - /** * @var array */ - static private $supportedFiles = [ + static private array $supportedFiles = [ self::FILE_EXT_LOG_ACC, self::FILE_EXT_LOG_ERR, self::FILE_EXT_LOG_SLOW, @@ -57,46 +53,51 @@ class Tester /** * @var array */ - static private $filesToClean = ['.user.ini']; + static private array $filesToClean = ['.user.ini']; /** * @var bool */ - private $debug; + private bool $debug; /** * @var array */ - private $clients; + private array $clients = []; + + /** + * @var LogReader + */ + private LogReader $logReader; /** * @var LogTool */ - private $logTool; + private LogTool $logTool; /** * Configuration template * * @var string|array */ - private $configTemplate; + private string|array $configTemplate; /** * The PHP code to execute * * @var string */ - private $code; + private string $code; /** * @var array */ - private $options; + private array $options; /** * @var string */ - private $fileName; + private string $fileName; /** * @var resource @@ -111,19 +112,19 @@ class Tester /** * @var array */ - private $ports = []; + private array $ports = []; /** - * @var string + * @var string|null */ - private $error; + private ?string $error = null; /** * The last response for the request call * - * @var Response + * @var Response|null */ - private $response; + private ?Response $response; /** * Clean all the created files up @@ -133,19 +134,19 @@ class Tester static public function clean($backTraceIndex = 1) { $filePrefix = self::getCallerFileName($backTraceIndex); - if (substr($filePrefix, -6) === 'clean.') { + if (str_ends_with($filePrefix, 'clean.')) { $filePrefix = substr($filePrefix, 0, -6); } $filesToClean = array_merge( array_map( - function($fileExtension) use ($filePrefix) { + function ($fileExtension) use ($filePrefix) { return $filePrefix . $fileExtension; }, self::$supportedFiles ), array_map( - function($fileExtension) { + function ($fileExtension) { return __DIR__ . '/' . $fileExtension; }, self::$filesToClean @@ -164,9 +165,10 @@ class Tester /** * Clean config files */ - static public function cleanConfigFiles() { + static public function cleanConfigFiles() + { if (is_dir(self::CONF_DIR)) { - foreach(glob(self::CONF_DIR . '/*.conf') as $name) { + foreach (glob(self::CONF_DIR . '/*.conf') as $name) { unlink($name); } rmdir(self::CONF_DIR); @@ -175,9 +177,10 @@ class Tester /** * @param int $backTraceIndex + * * @return string */ - static private function getCallerFileName($backTraceIndex = 1) + static private function getCallerFileName(int $backTraceIndex = 1): string { $backtrace = debug_backtrace(); if (isset($backtrace[$backTraceIndex]['file'])) { @@ -192,7 +195,7 @@ class Tester /** * @return bool|string */ - static public function findExecutable() + static public function findExecutable(): bool|string { $phpPath = getenv("TEST_PHP_EXECUTABLE"); for ($i = 0; $i < 2; $i++) { @@ -205,11 +208,11 @@ class Tester } if ($phpPath && is_dir($phpPath)) { - if (file_exists($phpPath."/fpm/php-fpm") && is_executable($phpPath."/fpm/php-fpm")) { + if (file_exists($phpPath . "/fpm/php-fpm") && is_executable($phpPath . "/fpm/php-fpm")) { /* gotcha */ - return $phpPath."/fpm/php-fpm"; + return $phpPath . "/fpm/php-fpm"; } - $phpSbinFpmi = $phpPath."/sbin/php-fpm"; + $phpSbinFpmi = $phpPath . "/sbin/php-fpm"; if (file_exists($phpSbinFpmi) && is_executable($phpSbinFpmi)) { return $phpSbinFpmi; } @@ -231,11 +234,11 @@ class Tester */ static public function skipIfAnyFileDoesNotExist($files) { - if (!is_array($files)) { + if ( ! is_array($files)) { $files = array($files); } foreach ($files as $file) { - if (!file_exists($file)) { + if ( ! file_exists($file)) { die("skip File $file does not exist"); } } @@ -245,11 +248,12 @@ class Tester * Skip test if config file is invalid. * * @param string $configTemplate + * * @throws \Exception */ static public function skipIfConfigFails(string $configTemplate) { - $tester = new self($configTemplate, '', [], self::getCallerFileName()); + $tester = new self($configTemplate, '', [], self::getCallerFileName()); $testResult = $tester->testConfig(); if ($testResult !== null) { self::clean(2); @@ -305,7 +309,7 @@ class Tester */ static public function skipIfPosixNotLoaded() { - if (!extension_loaded('posix')) { + if ( ! extension_loaded('posix')) { die('skip posix extension not loaded'); } } @@ -314,22 +318,25 @@ class Tester * Tester constructor. * * @param string|array $configTemplate - * @param string $code - * @param array $options - * @param string $fileName + * @param string $code + * @param array $options + * @param string|null $fileName + * @param bool|null $debug */ public function __construct( - $configTemplate, + string|array $configTemplate, string $code = '', array $options = [], - $fileName = null + string $fileName = null, + bool $debug = null ) { $this->configTemplate = $configTemplate; - $this->code = $code; - $this->options = $options; - $this->fileName = $fileName ?: self::getCallerFileName(); - $this->logTool = new LogTool(); - $this->debug = (bool) getenv('TEST_FPM_DEBUG'); + $this->code = $code; + $this->options = $options; + $this->fileName = $fileName ?: self::getCallerFileName(); + $this->debug = $debug !== null ? $debug : (bool)getenv('TEST_FPM_DEBUG'); + $this->logReader = new LogReader($this->debug); + $this->logTool = new LogTool($this->logReader, $this->debug); } /** @@ -338,6 +345,7 @@ class Tester public function setUserIni(string $ini) { $iniFile = __DIR__ . '/.user.ini'; + $this->trace('Setting .user.ini file', $ini, isFile: true); file_put_contents($iniFile, $ini); } @@ -350,7 +358,8 @@ class Tester public function testConfig() { $configFile = $this->createConfig(); - $cmd = self::findExecutable() . ' -t -y ' . $configFile . ' 2>&1'; + $cmd = self::findExecutable() . ' -t -y ' . $configFile . ' 2>&1'; + $this->trace('Testing config using command', $cmd, true); exec($cmd, $output, $code); if ($code) { return preg_replace("/\[.+?\]/", "", $output[0]); @@ -362,20 +371,20 @@ class Tester /** * Start PHP-FPM master process * - * @param array $extraArgs + * @param array $extraArgs Command extra arguments. + * @param bool $forceStderr Whether to output to stderr so error log is used. + * * @return bool * @throws \Exception */ - public function start(array $extraArgs = []) + public function start(array $extraArgs = [], bool $forceStderr = true) { $configFile = $this->createConfig(); - $desc = $this->outDesc ? [] : [1 => array('pipe', 'w'), 2 => array('redirect', 1)]; + $desc = $this->outDesc ? [] : [1 => array('pipe', 'w'), 2 => array('redirect', 1)]; $cmd = [self::findExecutable(), '-F', '-y', $configFile]; - if (!(isset($this->options[self::PHP_FPM_DISABLE_FORCE_STDERR]) && - $this->options[self::PHP_FPM_DISABLE_FORCE_STDERR] === true) - ) { + if ($forceStderr) { $cmd[] = '-O'; } @@ -383,10 +392,11 @@ class Tester $cmd[] = '--allow-to-run-as-root'; } $cmd = array_merge($cmd, $extraArgs); + $this->trace('Starting FPM using command:', $cmd, true); $this->masterProcess = proc_open($cmd, $desc, $pipes); register_shutdown_function( - function($masterProcess) use($configFile) { + function ($masterProcess) use ($configFile) { @unlink($configFile); if (is_resource($masterProcess)) { @proc_terminate($masterProcess); @@ -397,8 +407,9 @@ class Tester }, $this->masterProcess ); - if (!$this->outDesc !== false) { + if ( ! $this->outDesc !== false) { $this->outDesc = $pipes[1]; + $this->logReader->setStreamSource('{{MASTER:OUT}}', $this->outDesc); } return true; @@ -407,49 +418,35 @@ class Tester /** * Run until needle is found in the log. * - * @param string $needle - * @param int $max + * @param string $pattern Search pattern to find. + * * @return bool * @throws \Exception */ - public function runTill(string $needle, $max = 10) + public function runTill(string $pattern) { $this->start(); - $found = false; - for ($i = 0; $i < $max; $i++) { - $line = $this->getLogLine(); - if (is_null($line)) { - break; - } - if (preg_match($needle, $line) === 1) { - $found = true; - break; - } - } + $found = $this->logTool->expectPattern($pattern); $this->close(true); - if (!$found) { - return $this->error("The search pattern not found"); - } - - return true; + return $found; } /** * Check if connection works. * - * @param string $host - * @param null|string $successMessage - * @param null|string $errorMessage - * @param int $attempts - * @param int $delay + * @param string $host + * @param string|null $successMessage + * @param string|null $errorMessage + * @param int $attempts + * @param int $delay */ public function checkConnection( - $host = '127.0.0.1', - $successMessage = null, - $errorMessage = 'Connection failed', - $attempts = 20, - $delay = 50000 + string $host = '127.0.0.1', + string $successMessage = null, + ?string $errorMessage = 'Connection failed', + int $attempts = 20, + int $delay = 50000 ) { $i = 0; do { @@ -457,9 +454,10 @@ class Tester usleep($delay); } $fp = @fsockopen($host, $this->getPort()); - } while ((++$i < $attempts) && !$fp); + } while ((++$i < $attempts) && ! $fp); if ($fp) { + $this->trace('Checking connection successful'); $this->message($successMessage); fclose($fp); } else { @@ -471,22 +469,23 @@ class Tester /** * Execute request with parameters ordered for better checking. * - * @param string $address + * @param string $address * @param string|null $successMessage * @param string|null $errorMessage - * @param string $uri - * @param string $query - * @param array $headers + * @param string $uri + * @param string $query + * @param array $headers + * * @return Response */ public function checkRequest( string $address, string $successMessage = null, string $errorMessage = null, - $uri = '/ping', - $query = '', - $headers = [] - ) { + string $uri = '/ping', + string $query = '', + array $headers = [] + ): Response { return $this->request($query, $headers, $uri, $address, $successMessage, $errorMessage); } @@ -509,10 +508,11 @@ class Tester /** * Execute and check status request(s). * - * @param array $expectedFields + * @param array $expectedFields * @param string|null $address - * @param string $statusPath - * @param mixed $formats + * @param string $statusPath + * @param mixed $formats + * * @throws \Exception */ public function status( @@ -521,14 +521,14 @@ class Tester string $statusPath = '/status', $formats = ['plain', 'html', 'xml', 'json', 'openmetrics'] ) { - if (!is_array($formats)) { + if ( ! is_array($formats)) { $formats = [$formats]; } require_once "status.inc"; $status = new Status(); foreach ($formats as $format) { - $query = $format === 'plain' ? '' : $format; + $query = $format === 'plain' ? '' : $format; $response = $this->request($query, [], $statusPath, $address); $status->checkStatus($response, $expectedFields, $format); } @@ -537,10 +537,11 @@ class Tester /** * Get request params array. * - * @param string $query - * @param array $headers + * @param string $query + * @param array $headers * @param string|null $uri * @param string|null $scriptFilename + * * @return array */ private function getRequestParams( @@ -548,7 +549,7 @@ class Tester array $headers = [], string $uri = null, string $scriptFilename = null - ) { + ): array { if (is_null($uri)) { $uri = $this->makeSourceFile(); } @@ -560,7 +561,7 @@ class Tester 'SCRIPT_FILENAME' => $scriptFilename ?: $uri, 'SCRIPT_NAME' => $uri, 'QUERY_STRING' => $query, - 'REQUEST_URI' => $uri . ($query ? '?'.$query : ""), + 'REQUEST_URI' => $uri . ($query ? '?' . $query : ""), 'DOCUMENT_URI' => $uri, 'SERVER_SOFTWARE' => 'php/fcgiclient', 'REMOTE_ADDR' => '127.0.0.1', @@ -576,24 +577,25 @@ class Tester $headers ); - return array_filter($params, function($value) { - return !is_null($value); + return array_filter($params, function ($value) { + return ! is_null($value); }); } /** * Execute request. * - * @param string $query - * @param array $headers + * @param string $query + * @param array $headers * @param string|null $uri * @param string|null $address * @param string|null $successMessage - * @param string|null $errorMessage - * @param bool $connKeepAlive + * @param string|null $errorMessagereadLimit + * @param bool $connKeepAlive * @param string|null $scriptFilename = null - * @param bool $expectError - * @param int $readLimit + * @param bool $expectError + * @param int $readLimit + * * @return Response */ public function request( @@ -607,12 +609,13 @@ class Tester string $scriptFilename = null, bool $expectError = false, int $readLimit = -1, - ) { + ): Response { if ($this->hasError()) { return new Response(null, true); } $params = $this->getRequestParams($query, $headers, $uri, $scriptFilename); + $this->trace('Request params', $params); try { $this->response = new Response( @@ -636,37 +639,37 @@ class Tester if ($this->debug) { $this->response->debugOutput(); } + return $this->response; } /** * Execute multiple requests in parallel. * - * @param array|int $requests + * @param int|array $requests * @param string|null $address * @param string|null $successMessage * @param string|null $errorMessage - * @param bool $connKeepAlive - * @param int $readTimeout + * @param bool $connKeepAlive + * @param int $readTimeout + * * @return Response[] * @throws \Exception */ public function multiRequest( - $requests, + int|array $requests, string $address = null, string $successMessage = null, string $errorMessage = null, bool $connKeepAlive = false, int $readTimeout = 0 ) { - if ($this->hasError()) { - return new Response(null, true); - } - if (is_numeric($requests)) { $requests = array_fill(0, $requests, []); - } elseif (!is_array($requests)) { - throw new \Exception('Requests can be either numeric or array'); + } + + if ($this->hasError()) { + return array_map(fn($request) => new Response(null, true), $requests); } try { @@ -677,8 +680,9 @@ class Tester $requestData['headers'] ?? [], $requestData['uri'] ?? null ); + return [ - 'client' => $client, + 'client' => $client, 'requestId' => $client->async_request($params, false), ]; }, $requests); @@ -688,9 +692,11 @@ class Tester if ($this->debug) { $response->debugOutput(); } + return $response; }, $connections); $this->message($successMessage); + return $responses; } catch (\Exception $exception) { if ($errorMessage === null) { @@ -698,6 +704,8 @@ class Tester } else { $this->message($errorMessage); } + + return array_map(fn($request) => new Response(null, true), $requests); } } @@ -705,10 +713,11 @@ class Tester * Get client. * * @param string $address - * @param bool $keepAlive + * @param bool $keepAlive + * * @return Client */ - private function getClient(string $address = null, $keepAlive = false) + private function getClient(string $address = null, $keepAlive = false): Client { $address = $address ? $this->processTemplate($address) : $this->getAddr(); if ($address[0] === '/') { // uds @@ -716,7 +725,7 @@ class Tester $port = -1; } elseif ($address[0] === '[') { // ipv6 $addressParts = explode(']:', $address); - $host = $addressParts[0]; + $host = $addressParts[0]; if (isset($addressParts[1])) { $host .= ']'; $port = $addressParts[1]; @@ -725,15 +734,15 @@ class Tester } } else { // ipv4 $addressParts = explode(':', $address); - $host = $addressParts[0]; - $port = $addressParts[1] ?? $this->getPort(); + $host = $addressParts[0]; + $port = $addressParts[1] ?? $this->getPort(); } - if (!$keepAlive) { + if ( ! $keepAlive) { return new Client($host, $port); } - if (!isset($this->clients[$host][$port])) { + if ( ! isset($this->clients[$host][$port])) { $client = new Client($host, $port); $client->setKeepAlive(true); $this->clients[$host][$port] = $client; @@ -742,83 +751,6 @@ class Tester return $this->clients[$host][$port]; } - /** - * Display logs - * - * @param int $number - * @param string $ignore - */ - public function displayLog(int $number = 1, string $ignore = 'systemd') - { - /* Read $number lines or until EOF */ - while ($number > 0 || ($number < 0 && !feof($this->outDesc))) { - $a = fgets($this->outDesc); - if (empty($ignore) || !strpos($a, $ignore)) { - echo $a; - $number--; - } - } - } - - /** - * Get a single log line - * - * @return null|string - */ - private function getLogLine() - { - $read = [$this->outDesc]; - $write = null; - $except = null; - if (stream_select($read, $write, $except, $timeout=3)) { - return fgets($this->outDesc); - } else { - return null; - } - } - - /** - * Get log lines - * - * @param int $number - * @param bool $skipBlank - * @param string $ignore - * @return array - */ - public function getLogLines(int $number = 1, bool $skipBlank = false, string $ignore = 'systemd') - { - $lines = []; - /* Read $n lines or until EOF */ - while ($number > 0 || ($number < 0 && !feof($this->outDesc))) { - $line = $this->getLogLine(); - if (is_null($line)) { - break; - } - if ((empty($ignore) || !strpos($line, $ignore)) && (!$skipBlank || strlen(trim($line)) > 0)) { - $lines[] = $line; - $number--; - } - } - - if ($this->debug) { - foreach ($lines as $line) { - echo "LOG LINE: " . $line; - } - } - - return $lines; - } - - /** - * @return mixed|string - */ - public function getLastLogLine() - { - $lines = $this->getLogLines(); - - return $lines[0] ?? ''; - } - /** * @return string */ @@ -855,12 +787,13 @@ class Tester * Reload FPM by sending USR2 signal and optionally change config before that. * * @param string|array $configTemplate + * * @return string * @throws \Exception */ public function reload($configTemplate = null) { - if (!is_null($configTemplate)) { + if ( ! is_null($configTemplate)) { self::cleanConfigFiles(); $this->configTemplate = $configTemplate; $this->createConfig(); @@ -869,11 +802,23 @@ class Tester return $this->signal('USR2'); } + /** + * Reload FPM logs by sending USR1 signal. + * + * @return string + * @throws \Exception + */ + public function reloadLogs(): string + { + return $this->signal('USR1'); + } + /** * Send signal to the supplied PID or the server PID. * - * @param string $signal + * @param string $signal * @param int|null $pid + * * @return string */ public function signal($signal, int $pid = null) @@ -881,6 +826,8 @@ class Tester if (is_null($pid)) { $pid = $this->getPid(); } + $cmd = "kill -$signal $pid"; + $this->trace('Sending signal using command', $cmd, true); return exec("kill -$signal $pid"); } @@ -903,7 +850,6 @@ class Tester if ($terminate) { $this->terminate(); } - fclose($this->outDesc); proc_close($this->masterProcess); } @@ -911,6 +857,7 @@ class Tester * Create a config file. * * @param string $extension + * * @return string * @throws \Exception */ @@ -918,11 +865,11 @@ class Tester { if (is_array($this->configTemplate)) { $configTemplates = $this->configTemplate; - if (!isset($configTemplates['main'])) { + if ( ! isset($configTemplates['main'])) { throw new \Exception('The config template array has to have main config'); } $mainTemplate = $configTemplates['main']; - if (!is_dir(self::CONF_DIR)) { + if ( ! is_dir(self::CONF_DIR)) { mkdir(self::CONF_DIR); } foreach ($this->createPoolConfigs($configTemplates) as $name => $poolConfig) { @@ -944,29 +891,32 @@ class Tester * Create pool config templates. * * @param array $configTemplates + * * @return array * @throws \Exception */ private function createPoolConfigs(array $configTemplates) { - if (!isset($configTemplates['poolTemplate'])) { + if ( ! isset($configTemplates['poolTemplate'])) { unset($configTemplates['main']); + return $configTemplates; } $poolTemplate = $configTemplates['poolTemplate']; - $configs = []; + $configs = []; if (isset($configTemplates['count'])) { $start = $configTemplates['start'] ?? 1; - for ($i = $start; $i < $start + $configTemplates['count']; $i++) { + for ($i = $start; $i < $start + $configTemplates['count']; $i++) { $configs[$i] = str_replace('%index%', $i, $poolTemplate); } } elseif (isset($configTemplates['names'])) { - foreach($configTemplates['names'] as $name) { + foreach ($configTemplates['names'] as $name) { $configs[$name] = str_replace('%name%', $name, $poolTemplate); } } else { throw new \Exception('The config template requires count or names if poolTemplate set'); } + return $configs; } @@ -974,33 +924,37 @@ class Tester * Process template string. * * @param string $template + * * @return string */ private function processTemplate(string $template) { - $vars = [ - 'FILE:LOG:ACC' => ['getAbsoluteFile', self::FILE_EXT_LOG_ACC], - 'FILE:LOG:ERR' => ['getAbsoluteFile', self::FILE_EXT_LOG_ERR], - 'FILE:LOG:SLOW' => ['getAbsoluteFile', self::FILE_EXT_LOG_SLOW], - 'FILE:PID' => ['getAbsoluteFile', self::FILE_EXT_PID], - 'RFILE:LOG:ACC' => ['getRelativeFile', self::FILE_EXT_LOG_ACC], - 'RFILE:LOG:ERR' => ['getRelativeFile', self::FILE_EXT_LOG_ERR], + $vars = [ + 'FILE:LOG:ACC' => ['getAbsoluteFile', self::FILE_EXT_LOG_ACC], + 'FILE:LOG:ERR' => ['getAbsoluteFile', self::FILE_EXT_LOG_ERR], + 'FILE:LOG:SLOW' => ['getAbsoluteFile', self::FILE_EXT_LOG_SLOW], + 'FILE:PID' => ['getAbsoluteFile', self::FILE_EXT_PID], + 'RFILE:LOG:ACC' => ['getRelativeFile', self::FILE_EXT_LOG_ACC], + 'RFILE:LOG:ERR' => ['getRelativeFile', self::FILE_EXT_LOG_ERR], 'RFILE:LOG:SLOW' => ['getRelativeFile', self::FILE_EXT_LOG_SLOW], - 'RFILE:PID' => ['getRelativeFile', self::FILE_EXT_PID], - 'ADDR:IPv4' => ['getAddr', 'ipv4'], - 'ADDR:IPv4:ANY' => ['getAddr', 'ipv4-any'], - 'ADDR:IPv6' => ['getAddr', 'ipv6'], - 'ADDR:IPv6:ANY' => ['getAddr', 'ipv6-any'], - 'ADDR:UDS' => ['getAddr', 'uds'], - 'PORT' => ['getPort', 'ip'], - 'INCLUDE:CONF' => self::CONF_DIR . '/*.conf', - 'USER' => ['getUser'], - 'GROUP' => ['getGroup'], - 'UID' => ['getUid'], - 'GID' => ['getGid'], + 'RFILE:PID' => ['getRelativeFile', self::FILE_EXT_PID], + 'ADDR:IPv4' => ['getAddr', 'ipv4'], + 'ADDR:IPv4:ANY' => ['getAddr', 'ipv4-any'], + 'ADDR:IPv6' => ['getAddr', 'ipv6'], + 'ADDR:IPv6:ANY' => ['getAddr', 'ipv6-any'], + 'ADDR:UDS' => ['getAddr', 'uds'], + 'PORT' => ['getPort', 'ip'], + 'INCLUDE:CONF' => self::CONF_DIR . '/*.conf', + 'USER' => ['getUser'], + 'GROUP' => ['getGroup'], + 'UID' => ['getUid'], + 'GID' => ['getGid'], + 'MASTER:OUT' => 'pipe:1', + 'STDERR' => '/dev/stderr', + 'STDOUT' => '/dev/stdout', ]; $aliases = [ - 'ADDR' => 'ADDR:IPv4', + 'ADDR' => 'ADDR:IPv4', 'FILE:LOG' => 'FILE:LOG:ERR', ]; foreach ($aliases as $aliasName => $aliasValue) { @@ -1011,17 +965,19 @@ class Tester '/{{([a-zA-Z0-9:]+)(\[\w+\])?}}/', function ($matches) use ($vars) { $varName = $matches[1]; - if (!isset($vars[$varName])) { + if ( ! isset($vars[$varName])) { $this->error("Invalid config variable $varName"); + return 'INVALID'; } - $pool = $matches[2] ?? 'default'; + $pool = $matches[2] ?? 'default'; $varValue = $vars[$varName]; if (is_string($varValue)) { return $varValue; } $functionName = array_shift($varValue); - $varValue[] = $pool; + $varValue[] = $pool; + return call_user_func_array([$this, $functionName], $varValue); }, $template @@ -1031,6 +987,7 @@ class Tester /** * @param string $type * @param string $pool + * * @return string */ public function getAddr(string $type = 'ipv4', $pool = 'default') @@ -1045,9 +1002,9 @@ class Tester return $address; } - return sys_get_temp_dir().'/'. - hash('crc32', dirname($address)).'-'. - basename($address); + return sys_get_temp_dir() . '/' . + hash('crc32', dirname($address)) . '-' . + basename($address); } return $this->getHost($type) . ':' . $port; @@ -1056,19 +1013,20 @@ class Tester /** * @param string $type * @param string $pool - * @param bool $useAsId + * @param bool $useAsId + * * @return int */ public function getPort(string $type = 'ip', $pool = 'default', $useAsId = false) { - if ($type === 'uds' && !$useAsId) { + if ($type === 'uds' && ! $useAsId) { return -1; } if (isset($this->ports['values'][$pool])) { return $this->ports['values'][$pool]; } - $port = ($this->ports['last'] ?? 9000 + PHP_INT_SIZE - 1) + 1; + $port = ($this->ports['last'] ?? 9000 + PHP_INT_SIZE - 1) + 1; $this->ports['values'][$pool] = $this->ports['last'] = $port; return $port; @@ -1076,6 +1034,7 @@ class Tester /** * @param string $type + * * @return string */ public function getHost(string $type = 'ipv4') @@ -1096,6 +1055,7 @@ class Tester * Get listen address. * * @param string|null $template + * * @return string */ public function getListen($template = null) @@ -1111,45 +1071,55 @@ class Tester public function getPid() { $pidFile = $this->getFile('pid'); - if (!is_file($pidFile)) { - return (int) $this->error("PID file has not been created"); + if ( ! is_file($pidFile)) { + return (int)$this->error("PID file has not been created"); } $pidContent = file_get_contents($pidFile); - if (!is_numeric($pidContent)) { - return (int) $this->error("PID content '$pidContent' is not integer"); + if ( ! is_numeric($pidContent)) { + return (int)$this->error("PID content '$pidContent' is not integer"); } + $this->trace('PID found', $pidContent); - return (int) $pidContent; + return (int)$pidContent; } /** - * @param string $extension + * Get file path for resource file. + * + * @param string $extension * @param string|null $dir * @param string|null $name + * * @return string */ - private function getFile(string $extension, $dir = null, $name = null) + private function getFile(string $extension, string $dir = null, string $name = null): string { $fileName = (is_null($name) ? $this->fileName : $name . '.') . $extension; - return is_null($dir) ? $fileName : $dir . '/' . $fileName; + return is_null($dir) ? $fileName : $dir . '/' . $fileName; } /** + * Get absolute file path for the resource file used by templates. + * * @param string $extension + * * @return string */ - private function getAbsoluteFile(string $extension) + private function getAbsoluteFile(string $extension): string { return $this->getFile($extension); } /** + * Get relative file name for resource file used by templates. + * * @param string $extension + * * @return string */ - private function getRelativeFile(string $extension) + private function getRelativeFile(string $extension): string { $fileName = rtrim(basename($this->fileName), '.'); @@ -1157,14 +1127,17 @@ class Tester } /** - * @param string $extension - * @param string $prefix + * Get prefixed file. + * + * @param string $extension + * @param string|null $prefix + * * @return string */ - public function getPrefixedFile(string $extension, string $prefix = null) + public function getPrefixedFile(string $extension, string $prefix = null): string { $fileName = rtrim($this->fileName, '.'); - if (!is_null($prefix)) { + if ( ! is_null($prefix)) { $fileName = $prefix . '/' . basename($fileName); } @@ -1172,26 +1145,40 @@ class Tester } /** - * @param string $extension - * @param string $content + * Create a resource file. + * + * @param string $extension + * @param string $content * @param string|null $dir * @param string|null $name + * * @return string */ - private function makeFile(string $extension, string $content = '', $dir = null, $name = null) - { + private function makeFile( + string $extension, + string $content = '', + string $dir = null, + string $name = null, + bool $overwrite = true + ): string { $filePath = $this->getFile($extension, $dir, $name); + if ( ! $overwrite && is_file($filePath)) { + return $filePath; + } file_put_contents($filePath, $content); + $this->trace('Created file: ' . $filePath, $content, isFile: true); return $filePath; } /** + * Create a source code file. + * * @return string */ - public function makeSourceFile() + public function makeSourceFile(): string { - return $this->makeFile('src.php', $this->code); + return $this->makeFile('src.php', $this->code, overwrite: false); } /** @@ -1205,26 +1192,34 @@ class Tester } /** - * @param string $msg + * Display error. + * + * @param string $msg * @param \Exception|null $exception + * + * @return false */ - private function error($msg, \Exception $exception = null) + private function error($msg, \Exception $exception = null): bool { - $this->error = 'ERROR: ' . $msg; + $this->error = 'ERROR: ' . $msg; if ($exception) { $this->error .= '; EXCEPTION: ' . $exception->getMessage(); } $this->error .= "\n"; echo $this->error; + + return false; } /** + * Check whether any error was set. + * * @return bool */ private function hasError() { - return !is_null($this->error) || !is_null($this->logTool->getError()); + return ! is_null($this->error) || ! is_null($this->logTool->getError()); } /** @@ -1232,14 +1227,16 @@ class Tester * * @param string $extension * @param string $prefix + * * @return bool */ public function expectFile(string $extension, $prefix = null) { $filePath = $this->getPrefixedFile($extension, $prefix); - if (!file_exists($filePath)) { + if ( ! file_exists($filePath)) { return $this->error("The file $filePath does not exist"); } + $this->trace('File path exists as expected', $filePath); return true; } @@ -1249,6 +1246,7 @@ class Tester * * @param string $extension * @param string $prefix + * * @return bool */ public function expectNoFile(string $extension, $prefix = null) @@ -1257,6 +1255,7 @@ class Tester if (file_exists($filePath)) { return $this->error("The file $filePath exists"); } + $this->trace('File path does not exist as expected', $filePath); return true; } @@ -1265,8 +1264,8 @@ class Tester * Expect message to be written to FastCGI error stream. * * @param string $message - * @param int $limit - * @param int $repeat + * @param int $limit + * @param int $repeat */ public function expectFastCGIErrorMessage( string $message, @@ -1280,37 +1279,74 @@ class Tester /** * Expect reloading lines to be logged. * - * @param int $socketCount + * @param int $socketCount + * @param bool $expectInitialProgressMessage + * @param bool $expectReloadingMessage + * + * @throws \Exception */ - public function expectLogReloadingNotices($socketCount = 1) + public function expectLogReloadingNotices( + int $socketCount = 1, + bool $expectInitialProgressMessage = true, + bool $expectReloadingMessage = true + ) { + $this->logTool->expectReloadingLines( + $socketCount, + $expectInitialProgressMessage, + $expectReloadingMessage + ); + } + + /** + * Expect reloading lines to be logged. + * + * @throws \Exception + */ + public function expectLogReloadingLogsNotices() { - $this->logTool->expectReloadingLines($this->getLogLines($socketCount + 4)); + $this->logTool->expectReloadingLogsLines(); } /** * Expect starting lines to be logged. + * @throws \Exception */ public function expectLogStartNotices() { - $this->logTool->expectStartingLines($this->getLogLines(2)); + $this->logTool->expectStartingLines(); } /** * Expect terminating lines to be logged. + * @throws \Exception */ public function expectLogTerminatingNotices() { - $this->logTool->expectTerminatorLines($this->getLogLines(-1)); + $this->logTool->expectTerminatorLines(); + } + + /** + * Expect log pattern in logs. + * + * @param string $pattern Log pattern + * + * @throws \Exception + */ + public function expectLogPattern(string $pattern) + { + $this->logTool->expectPattern($pattern); } /** * Expect log message that can span multiple lines. * * @param string $message - * @param int $limit - * @param int $repeat - * @param bool $decorated - * @param bool $wrapped + * @param int $limit + * @param int $repeat + * @param bool $decorated + * @param bool $wrapped + * + * @throws \Exception */ public function expectLogMessage( string $message, @@ -1321,135 +1357,180 @@ class Tester ) { $this->logTool->setExpectedMessage($message, $limit, $repeat); if ($wrapped) { - $logLines = $this->getLogLines(-1, true); - $this->logTool->checkWrappedMessage($logLines, true, $decorated); + $this->logTool->checkWrappedMessage(true, $decorated); } else { - $logLines = $this->getLogLines(1, true); - $this->logTool->checkTruncatedMessage($logLines[0] ?? ''); - } - if ($this->debug) { - $this->message("-------------- LOG LINES: -------------"); - var_dump($logLines); - $this->message("---------------------------------------\n"); + $this->logTool->checkTruncatedMessage(); } } /** * Expect a single log line. * - * @param string $message + * @param string $message The expected message. + * @param bool $isStdErr Whether it is logged to stderr. + * @param bool $decorated Whether the log lines are decorated. + * * @return bool + * @throws \Exception */ - public function expectLogLine(string $message, bool $is_stderr = true) - { + public function expectLogLine( + string $message, + bool $isStdErr = true, + bool $decorated = true + ): bool { $messageLen = strlen($message); - $limit = $messageLen > 1024 ? $messageLen + 16 : 1024; + $limit = $messageLen > 1024 ? $messageLen + 16 : 1024; $this->logTool->setExpectedMessage($message, $limit); - $logLines = $this->getLogLines(1, true); - if ($this->debug) { - $this->message("LOG LINE: " . ($logLines[0] ?? '')); - } - return $this->logTool->checkWrappedMessage($logLines, false, true, $is_stderr); + return $this->logTool->checkWrappedMessage(false, $decorated, $isStdErr); } /** * Expect log entry. * - * @param string $type The log type - * @param string $message The expected message - * @param string|null $pool The pool for pool prefixed log entry - * @param int $count The number of items + * @param string $type The log type + * @param string $message The expected message + * @param string|null $pool The pool for pool prefixed log entry + * @param int $count The number of items + * @param bool $checkAllLogs Whether to also check past logs. + * * @return bool + * @throws \Exception */ - private function expectLogEntry(string $type, string $message, $pool = null, $count = 1) - { + private function expectLogEntry( + string $type, + string $message, + string $pool = null, + int $count = 1, + bool $checkAllLogs = false + ): bool { for ($i = 0; $i < $count; $i++) { - if (!$this->logTool->expectEntry($type, $this->getLastLogLine(), $message, $pool)) { + if ( ! $this->logTool->expectEntry($type, $message, $pool, $checkAllLogs)) { return false; } } + return true; } /** * Expect a log debug message. * - * @param string $message + * @param string $message * @param string|null $pool - * @param int $count + * @param int $count + * @param bool $checkAllLogs Whether to also check past logs. + * * @return bool + * @throws \Exception */ - public function expectLogDebug(string $message, $pool = null, $count = 1) - { - return $this->expectLogEntry(LogTool::DEBUG, $message, $pool, $count); + public function expectLogDebug( + string $message, + string $pool = null, + int $count = 1, + bool $checkAllLogs = false + ): bool { + return $this->expectLogEntry(LogTool::DEBUG, $message, $pool, $count, $checkAllLogs); } /** * Expect a log notice. * - * @param string $message + * @param string $message * @param string|null $pool - * @param int $count + * @param int $count + * @param bool $checkAllLogs Whether to also check past logs. + * * @return bool + * @throws \Exception */ - public function expectLogNotice(string $message, $pool = null, $count = 1) - { - return $this->expectLogEntry(LogTool::NOTICE, $message, $pool, $count); + public function expectLogNotice( + string $message, + string $pool = null, + int $count = 1, + bool $checkAllLogs = false + ): bool { + return $this->expectLogEntry(LogTool::NOTICE, $message, $pool, $count, $checkAllLogs); } /** * Expect a log warning. * - * @param string $message + * @param string $message * @param string|null $pool - * @param int $count + * @param int $count + * @param bool $checkAllLogs Whether to also check past logs. + * * @return bool + * @throws \Exception */ - public function expectLogWarning(string $message, $pool = null, $count = 1) - { - return $this->expectLogEntry(LogTool::WARNING, $message, $pool, $count); + public function expectLogWarning( + string $message, + string $pool = null, + int $count = 1, + bool $checkAllLogs = false + ): bool { + return $this->expectLogEntry(LogTool::WARNING, $message, $pool, $count, $checkAllLogs); } /** * Expect a log error. * - * @param string $message + * @param string $message * @param string|null $pool - * @param int $count + * @param int $count + * @param bool $checkAllLogs Whether to also check past logs. + * * @return bool + * @throws \Exception */ - public function expectLogError(string $message, $pool = null, $count = 1) - { - return $this->expectLogEntry(LogTool::ERROR, $message, $pool, $count); + public function expectLogError( + string $message, + string $pool = null, + int $count = 1, + bool $checkAllLogs = false + ): bool { + return $this->expectLogEntry(LogTool::ERROR, $message, $pool, $count, $checkAllLogs); } /** * Expect a log alert. * - * @param string $message + * @param string $message * @param string|null $pool - * @param int $count + * @param int $count + * @param bool $checkAllLogs Whether to also check past logs. + * * @return bool + * @throws \Exception */ - public function expectLogAlert(string $message, $pool = null, $count = 1) - { - return $this->expectLogEntry(LogTool::ALERT, $message, $pool, $count); + public function expectLogAlert( + string $message, + string $pool = null, + int $count = 1, + bool $checkAllLogs = false + ): bool { + return $this->expectLogEntry(LogTool::ALERT, $message, $pool, $count, $checkAllLogs); } /** * Expect no log lines to be logged. * * @return bool + * @throws \Exception */ - public function expectNoLogMessages() + public function expectNoLogMessages(): bool { - $logLines = $this->getLogLines(-1, true); - if (!empty($logLines)) { + $logLine = $this->logReader->getLine(timeoutSeconds: 0, timeoutMicroseconds: 1000); + if ($logLine === "") { + $logLine = $this->logReader->getLine(timeoutSeconds: 0, timeoutMicroseconds: 1000); + } + if ($logLine !== null) { return $this->error( - "Expected no log lines but following lines logged:\n" . implode("\n", $logLines) + "Expected no log lines but following line logged: $logLine" ); } + $this->trace('No log message received as expected'); return true; } @@ -1458,52 +1539,103 @@ class Tester * Expect log config options * * @param array $options + * * @return bool + * @throws \Exception */ public function expectLogConfigOptions(array $options) { - $configOptions = $this->getConfigOptions(); foreach ($options as $name => $value) { - if (!isset($configOptions[$name])) { - return $this->error("Expected config option: {$name} = {$value} but {$name} is not set"); - } - if ($configOptions[$name] != $value) { - return $this->error( - "Expected config option: {$name} = {$value} but got: {$name} = {$configOptions[$name]}" - ); - } + $this->expectLogNotice("\s+$name\s=\s$value", checkAllLogs: true); } return true; } /** - * Get set config options - * - * @return array + * Print content of access log. */ - private function getConfigOptions() + public function printAccessLog() { - $options = []; - - foreach ($this->getLogLines(-1) as $line) { - preg_match('/.+NOTICE:\s+(.+)\s=\s(.+)/', $line, $matches); - if ($matches) { - $options[$matches[1]] = $matches[2]; - } + $accessLog = $this->getFile('acc.log'); + if (is_file($accessLog)) { + print file_get_contents($accessLog); } + } - return $options; + /** + * Read all log entries. + * + * @param string $type The log type + * @param string $message The expected message + * @param string|null $pool The pool for pool prefixed log entry + * + * @return bool + * @throws \Exception + */ + public function readAllLogEntries(string $type, string $message, string $pool = null): bool + { + return $this->logTool->readAllEntries($type, $message, $pool); } /** - * Print content of access log. + * Read all log entries. + * + * @param string $message The expected message + * @param string|null $pool The pool for pool prefixed log entry + * + * @return bool + * @throws \Exception */ - public function printAccessLog() + public function readAllLogNotices(string $message, string $pool = null): bool { - $accessLog = $this->getFile('acc.log'); - if (is_file($accessLog)) { - print file_get_contents($accessLog); + return $this->readAllLogEntries(LogTool::NOTICE, $message, $pool); + } + + /** + * Switch the logs source. + * + * @param string $source The source file path or name if log is a pipe. + * + * @throws \Exception + */ + public function switchLogSource(string $source) + { + $this->trace('Switching log descriptor to:', $source); + $this->logReader->setFileSource($source, $this->processTemplate($source)); + } + + /** + * Trace execution by printing supplied message only in debug mode. + * + * @param string $title Trace title to print if supplied. + * @param string|array|null $message Message to print. + * @param bool $isCommand Whether message is a command array. + */ + private function trace( + string $title, + string|array $message = null, + bool $isCommand = false, + bool $isFile = false + ): void { + if ($this->debug) { + echo "\n"; + echo ">>> $title\n"; + if (is_array($message)) { + if ($isCommand) { + echo implode(' ', $message) . "\n"; + } else { + print_r($message); + } + } elseif ($message !== null) { + if ($isFile) { + $this->logReader->printSeparator(); + } + echo $message . "\n"; + if ($isFile) { + $this->logReader->printSeparator(); + } + } } } }