diff --git a/.circleci/config.yml b/.circleci/config.yml index 78520332dfc7e..0ce68b36d9013 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -153,6 +153,7 @@ jobs: `#--enable-werror` - run: name: make + no_output_timeout: 30m command: make -j2 > /dev/null - run: name: make install diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5603700ecc98d..9f9d182031d04 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -44,6 +44,7 @@ /ext/pdo_sqlite @SakiTakamachi /ext/pgsql @devnexen /ext/random @TimWolla @zeriyoshi +/ext/reflection @DanielEScherzer /ext/session @Girgias /ext/simplexml @nielsdos /ext/soap @nielsdos diff --git a/.github/actions/configure-gentoo/action.yml b/.github/actions/configure-gentoo/action.yml new file mode 100644 index 0000000000000..e1ae914681fb0 --- /dev/null +++ b/.github/actions/configure-gentoo/action.yml @@ -0,0 +1,81 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false + skipSlow: + default: false + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + ./buildconf --force + ./configure \ + --enable-option-checking=fatal \ + --prefix=/usr \ + --with-libdir=lib64 \ + --enable-phpdbg \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + ${{ inputs.skipSlow == 'false' && '--with-pgsql' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-pgsql' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-sqlite' || '' }} \ + --enable-intl \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --with-xpm \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + ${{ inputs.skipSlow == 'false' && '--with-tidy' || '' }} \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline \ + --enable-mbstring \ + --with-iconv \ + --with-curl \ + --with-gettext \ + --enable-sockets \ + --with-bz2 \ + --with-openssl \ + --with-gmp \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + ${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + ${{ inputs.skipSlow == 'false' && '--enable-dl-test=shared' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-ldap' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-ldap-sasl' || '' }} \ + --with-password-argon2 \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --with-cdb \ + --enable-flatfile \ + --enable-inifile \ + --with-tcadb \ + --with-lmdb \ + --with-qdbm \ + ${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-odbc=unixODBC,/usr' || '' }} \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-dblib' || '' }} \ + --enable-werror \ + ${{ inputs.configurationParameters }} || cat config.log diff --git a/.github/actions/test-gentoo/action.yml b/.github/actions/test-gentoo/action.yml new file mode 100644 index 0000000000000..ec9fb0b70c6a3 --- /dev/null +++ b/.github/actions/test-gentoo/action.yml @@ -0,0 +1,34 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + # XXX: Set up other database tests? + # XXX: These tests are not running containerized + export MYSQL_TEST_USER=ci + export MYSQL_TEST_PASSWD=ci + if [[ -z "$PDO_MYSQL_TEST_DSN" ]]; then + export PDO_MYSQL_TEST_DSN="mysql:host=localhost;dbname=test" + fi + export PDO_MYSQL_TEST_USER=ci + export PDO_MYSQL_TEST_PASS=ci + export PGSQL_TEST_CONNSTR="host=localhost dbname=test port=5432 user=ci password=ci" + if [[ -z "$PDO_PGSQL_TEST_DSN" ]]; then + export PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=ci password=ci" + fi + # Slow tests criteron is doubled because this runner isn't as fast as others + export SKIP_IO_CAPTURE_TESTS=1 + export STACK_LIMIT_DEFAULTS_CHECK=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -j$(nproc) \ + -g FAIL,BORK,LEAK,XLEAK \ + --no-progress \ + --show-diff \ + --show-slow 2000 \ + --set-timeout 120 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2377286ca830c..c9e6850604312 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -17,6 +17,9 @@ on: run_alpine: required: true type: boolean + run_linux_ppc64: + required: true + type: boolean run_macos_arm64: required: true type: boolean @@ -35,6 +38,44 @@ on: permissions: contents: read jobs: + LINUX_PPC64: + if: inputs.run_linux_ppc64 + name: LINUX_PPC64_ASAN_UBSAN_DEBUG_ZTS + # This runs on a self-hosted runner; see https://wiki.php.net/systems/ci + runs-on: [self-hosted, gentoo, ppc64] + steps: + - name: git checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed packages" + cat /var/lib/portage/world + echo "::endgroup::" + - name: ./configure + uses: ./.github/actions/configure-gentoo + with: + configurationParameters: >- + CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" + LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" + CC=clang-17 + CXX=clang++-17 + --enable-debug + --enable-zts + skipSlow: false # FIXME: This should likely include slow extensions + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + # Skip an install action for now + - name: Tests + uses: ./.github/actions/test-gentoo + # There is no PPC JIT, so rip this out + with: + runTestsParameters: >- + --asan -x ALPINE: if: inputs.run_alpine name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 4eaa8fee40eab..7198ec22d67e2 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -140,7 +140,7 @@ jobs: name: LINUX_X32_DEBUG_ZTS runs-on: ubuntu-latest container: - image: ubuntu:20.04 + image: ubuntu:22.04 env: MYSQL_TEST_HOST: mysql PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml index 5cdd70489343f..2bb895e96b668 100644 --- a/.github/workflows/root.yml +++ b/.github/workflows/root.yml @@ -48,16 +48,16 @@ jobs: with: asan_ubuntu_version: ${{ (((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 5) || matrix.branch.version[0] >= 9) && '24.04') - || '20.04' }} + || '22.04' }} branch: ${{ matrix.branch.ref }} community_verify_type_inference: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} libmysqlclient_with_mysqli: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1) }} run_alpine: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} + run_linux_ppc64: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} run_macos_arm64: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} ubuntu_version: ${{ (((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 5) || matrix.branch.version[0] >= 9) && '24.04') - || ((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 3) && '22.04') - || '20.04' }} + || '22.04' }} windows_version: ${{ ((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9) && '2022' || '2019' }} skip_symfony: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} skip_wordpress: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} diff --git a/.gitignore b/.gitignore index d8cb25a1a109c..91120a5fa6b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,9 @@ # Libtool library files generated during build process *.la +# Mac shared library files generated during build process +*.dylib + # Directories created by Libtool for storing generated library files .libs/ diff --git a/NEWS b/NEWS index 1968cb701e9bc..5dd84f81c0d96 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,96 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.4.5 +10 Apr 2025, PHP 8.4.6 + +- BCMath: + . Fixed pointer subtraction for scale. (SakiTakamachi) + +- Core: + . Fixed property hook backing value access in multi-level inheritance. + (ilutov) + . Fixed accidentally inherited default value in overridden virtual properties. + (ilutov) + . Fixed bug GH-17376 (Broken JIT polymorphism for property hooks added to + child class). (ilutov) + . Fixed bug GH-17913 (ReflectionFunction::isDeprecated() returns incorrect + results for closures created from magic __call()). (timwolla) + . Fixed bug GH-17941 (Stack-use-after-return with lazy objects and hooks). + (nielsdos) + . Fixed bug GH-17988 (Incorrect handling of hooked props without get hook in + get_object_vars()). (ilutov) + . Fixed bug GH-17998 (Skipped lazy object initialization on primed + SIMPLE_WRITE cache). (ilutov) + . Fixed bug GH-17998 (Assignment to backing value in set hook of lazy proxy + calls hook again). (ilutov) + . Fixed bug GH-17961 (use-after-free during dl()'ed module class destruction). + (Arnaud) + . Fixed bug GH-15367 (dl() of module with aliased class crashes in shutdown). + (Arnaud) + . Fixed OSS-Fuzz #403308724. (nielsdos) + . Fixed bug GH-13193 again (Significant performance degradation in 'foreach'). + (nielsdos) + +- DBA: + . Fixed assertion violation when opening the same file with dba_open + multiple times. (chschneider) + +- DOM: + . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos) + . Fix weird unpack behaviour in DOM. (nielsdos) + . Fixed bug GH-18090 (DOM: Svg attributes and tag names are being lowercased). + (nielsdos) + . Fix xinclude destruction of live attributes. (nielsdos) + +- Fuzzer: + . Fixed bug GH-18081 (Memory leaks in error paths of fuzzer SAPI). + (Lung-Alexandra) + +- GD: + . Fixed bug GH-17984 (calls with arguments as array with references). + (David Carlier) + +- LDAP: + . Fixed bug GH-18015 (Error messages for ldap_mod_replace are confusing). + (nielsdos) + +- Mbstring: + . Fixed bug GH-17989 (mb_output_handler crash with unset + http_output_conv_mimetypes). (nielsdos) + +- Opcache: + . Fixed bug GH-15834 (Segfault with hook "simple get" cache slot and minimal + JIT). (nielsdos) + . Fixed bug GH-17966 (Symfony JIT 1205 assertion failure). (nielsdos) + . Fixed bug GH-18037 (SEGV Zend/zend_execute.c). (nielsdos) + . Fixed bug GH-18050 (IN_ARRAY optimization in DFA pass is broken). (ilutov) + . Fixed bug GH-18113 (stack-buffer-overflow ext/opcache/jit/ir/ir_sccp.c). + (nielsdos) + . Fixed bug GH-18112 (NULL access with preloading and INI option). (nielsdos) + . Fixed bug GH-18107 (Opcache CFG jmp optimization with try-finally breaks + the exception table). (nielsdos) + +- PDO: + . Fix memory leak when destroying PDORow. (nielsdos) + +- Standard: + . Fix memory leaks in array_any() / array_all(). (nielsdos) + +- SOAP: + . Fixed bug #66049 (Typemap can break parsing in parse_packet_soap leading to + a segfault) . (Remi) + +- SPL: + . Fixed bug GH-18018 (RC1 data returned from offsetGet causes UAF in + ArrayObject). (nielsdos) + +- Treewide: + . Fixed bug GH-17736 (Assertion failure zend_reference_destroy()). (nielsdos) + +- Windows: + . Fixed bug GH-17836 (zend_vm_gen.php shouldn't break on Windows line + endings). (DanielEScherzer) + +27 Feb 2025, PHP 8.4.5 - BCMath: . Fixed bug GH-17398 (bcmul memory leak). (SakiTakamachi) @@ -21,6 +111,8 @@ PHP NEWS (DanielEScherzer) . Fixed bug GH-17866 (zend_mm_heap corrupted error after upgrading from 8.4.3 to 8.4.4). (nielsdos) + . Fixed GHSA-rwp7-7vc6-8477 (Reference counting in php_request_shutdown + causes Use-After-Free). (CVE-2024-11235) (ilutov) - DOM: . Fixed bug GH-17609 (Typo in error message: Dom\NO_DEFAULT_NS instead of @@ -30,10 +122,6 @@ PHP NEWS . Fixed bug GH-17847 (xinclude destroys live node). (nielsdos) . Fix using Dom\Node with Dom\XPath callbacks. (nielsdos) -- GD: - . Fixed bug GH-17703 (imagescale with both width and height negative values - triggers only an Exception on width). (David Carlier) - - FFI: . Fix FFI Parsing of Pointer Declaration Lists. (davnotdev) @@ -42,6 +130,8 @@ PHP NEWS (Jakub Zelenka) - GD: + . Fixed bug GH-17703 (imagescale with both width and height negative values + triggers only an Exception on width). (David Carlier) . Fixed bug GH-17772 (imagepalettetotruecolor crash with memory_limit=2M). (David Carlier) @@ -49,6 +139,11 @@ PHP NEWS . Fixed bug GH-17704 (ldap_search fails when $attributes contains a non-packed array with numerical keys). (nielsdos, 7u83) +- LibXML: + . Fixed GHSA-wg4p-4hqh-c3g9 (Reocurrence of #72714). (nielsdos) + . Fixed GHSA-p3x9-6h7p-cgfc (libxml streams use wrong `content-type` header + when requesting a redirected resource). (CVE-2025-1219) (timwolla) + - MBString: . Fixed bug GH-17503 (Undefined float conversion in mb_convert_variables). (cmb) @@ -90,9 +185,17 @@ PHP NEWS - Streams: . Fixed bug GH-17650 (realloc with size 0 in user_filters.c). (nielsdos) . Fix memory leak on overflow in _php_stream_scandir(). (nielsdos) + . Fixed GHSA-hgf5-96fm-v528 (Stream HTTP wrapper header check might omit + basic auth header). (CVE-2025-1736) (Jakub Zelenka) + . Fixed GHSA-52jp-hrpf-2jff (Stream HTTP wrapper truncate redirect location + to 1024 bytes). (CVE-2025-1861) (Jakub Zelenka) + . Fixed GHSA-pcmh-g36c-qc44 (Streams HTTP wrapper does not fail for headers + without colon). (CVE-2025-1734) (Jakub Zelenka) + . Fixed GHSA-v8xr-gpvj-cx9g (Header parser of `http` stream wrapper does not + handle folded headers). (CVE-2025-1217) (Jakub Zelenka) - Windows: - . Fixed phpize for Windows 11 (24H2). (Bob) + . Fixed phpize for Windows 11 (24H2). (bwoebi) . Fixed GH-17855 (CURL_STATICLIB flag set even if linked with shared lib). (cmb) @@ -102,7 +205,7 @@ PHP NEWS . Fix memory leak when encoding check fails. (nielsdos) . Fix zlib support for large files. (nielsdos) -30 Jan 2025, PHP 8.4.4 +13 Feb 2025, PHP 8.4.4 - Core: . Fixed bug GH-17234 (Numeric parent hook call fails with assertion). @@ -221,7 +324,7 @@ PHP NEWS . Fixed bug GH-17139 (Fix zip_entry_name() crash on invalid entry). (nielsdos) -02 Jan 2025, PHP 8.4.3 +16 Jan 2025, PHP 8.4.3 - BcMath: . Fixed bug GH-17049 (Correctly compare 0 and -0). (Saki Takamachi) @@ -350,7 +453,7 @@ PHP NEWS - XML: . Fixed bug GH-1718 (unreachable program point in zend_hash). (nielsdos) -05 Dec 2024, PHP 8.4.2 +19 Dec 2024, PHP 8.4.2 - BcMath: . Fixed bug GH-16978 (Avoid unnecessary padding with leading zeros). diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index ce2a19f2e8fe9..2c3aaae065997 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -407,40 +407,28 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) zend_call_info *call_info = func_info->callee_info; do { - if (call_info->caller_call_opline - && call_info->caller_call_opline->opcode == ZEND_DO_ICALL + zend_op *op = call_info->caller_init_opline; + + if ((op->opcode == ZEND_FRAMELESS_ICALL_2 + || (op->opcode == ZEND_FRAMELESS_ICALL_3 && (op + 1)->op1_type == IS_CONST)) && call_info->callee_func - && zend_string_equals_literal(call_info->callee_func->common.function_name, "in_array") - && (call_info->caller_init_opline->extended_value == 2 - || (call_info->caller_init_opline->extended_value == 3 - && (call_info->caller_call_opline - 1)->opcode == ZEND_SEND_VAL - && (call_info->caller_call_opline - 1)->op1_type == IS_CONST))) { - - zend_op *send_array; - zend_op *send_needly; + && zend_string_equals_literal_ci(call_info->callee_func->common.function_name, "in_array")) { + bool strict = 0; + bool has_opdata = op->opcode == ZEND_FRAMELESS_ICALL_3; ZEND_ASSERT(!call_info->is_prototype); - if (call_info->caller_init_opline->extended_value == 2) { - send_array = call_info->caller_call_opline - 1; - send_needly = call_info->caller_call_opline - 2; - } else { - if (zend_is_true(CT_CONSTANT_EX(op_array, (call_info->caller_call_opline - 1)->op1.constant))) { + if (has_opdata) { + if (zend_is_true(CT_CONSTANT_EX(op_array, (op + 1)->op1.constant))) { strict = 1; } - send_array = call_info->caller_call_opline - 2; - send_needly = call_info->caller_call_opline - 3; } - if (send_array->opcode == ZEND_SEND_VAL - && send_array->op1_type == IS_CONST - && Z_TYPE_P(CT_CONSTANT_EX(op_array, send_array->op1.constant)) == IS_ARRAY - && (send_needly->opcode == ZEND_SEND_VAL - || send_needly->opcode == ZEND_SEND_VAR) - ) { + if (op->op2_type == IS_CONST + && Z_TYPE_P(CT_CONSTANT_EX(op_array, op->op2.constant)) == IS_ARRAY) { bool ok = 1; - HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, send_array->op1.constant)); + HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant)); HashTable *dst; zval *val, tmp; zend_ulong idx; @@ -471,59 +459,15 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) } if (ok) { - uint32_t op_num = send_needly - op_array->opcodes; - zend_ssa_op *ssa_op = ssa->ops + op_num; - - if (ssa_op->op1_use >= 0) { - /* Reconstruct SSA */ - int var_num = ssa_op->op1_use; - zend_ssa_var *var = ssa->vars + var_num; - - ZEND_ASSERT(ssa_op->op1_def < 0); - zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use); - ssa_op->op1_use = -1; - ssa_op->op1_use_chain = -1; - op_num = call_info->caller_call_opline - op_array->opcodes; - ssa_op = ssa->ops + op_num; - ssa_op->op1_use = var_num; - ssa_op->op1_use_chain = var->use_chain; - var->use_chain = op_num; - } - ZVAL_ARR(&tmp, dst); /* Update opcode */ - call_info->caller_call_opline->opcode = ZEND_IN_ARRAY; - call_info->caller_call_opline->extended_value = strict; - call_info->caller_call_opline->op1_type = send_needly->op1_type; - call_info->caller_call_opline->op1.num = send_needly->op1.num; - call_info->caller_call_opline->op2_type = IS_CONST; - call_info->caller_call_opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp); - if (call_info->caller_init_opline->extended_value == 3) { - MAKE_NOP(call_info->caller_call_opline - 1); - } - MAKE_NOP(call_info->caller_init_opline); - MAKE_NOP(send_needly); - MAKE_NOP(send_array); - removed_ops++; - - op_num = call_info->caller_call_opline - op_array->opcodes; - ssa_op = ssa->ops + op_num; - if (ssa_op->result_def >= 0) { - int var = ssa_op->result_def; - int use = ssa->vars[var].use_chain; - - /* If the result is used only in a JMPZ/JMPNZ, replace result type with - * IS_TMP_VAR, which will enable use of smart branches. Don't do this - * in other cases, as not all opcodes support both VAR and TMP. */ - if (ssa->vars[var].phi_use_chain == NULL - && ssa->ops[use].op1_use == var - && ssa->ops[use].op1_use_chain == -1 - && (op_array->opcodes[use].opcode == ZEND_JMPZ - || op_array->opcodes[use].opcode == ZEND_JMPNZ)) { - call_info->caller_call_opline->result_type = IS_TMP_VAR; - op_array->opcodes[use].op1_type = IS_TMP_VAR; - } + op->opcode = ZEND_IN_ARRAY; + op->extended_value = strict; + op->op2.constant = zend_optimizer_add_literal(op_array, &tmp); + if (has_opdata) { + MAKE_NOP(op + 1); + removed_ops++; } } } diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index a05cf6fb79235..a0d08b67aa70c 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -143,7 +143,11 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * end = blocks + block_map[op_array->try_catch_array[j].finally_op]; while (b != end) { if (b->flags & ZEND_BB_REACHABLE) { - op_array->try_catch_array[j].try_op = op_array->try_catch_array[j].catch_op; + /* In case we get here, there is no live try block but there is a live finally block. + * If we do have catch_op set, we need to set it to the first catch block to satisfy + * the constraint try_op <= catch_op <= finally_op */ + op_array->try_catch_array[j].try_op = + op_array->try_catch_array[j].catch_op ? op_array->try_catch_array[j].catch_op : b->start; changed = 1; zend_mark_reachable(op_array->opcodes, cfg, blocks + block_map[op_array->try_catch_array[j].try_op]); break; diff --git a/Zend/tests/ghsa-rwp7-7vc6-8477_001.phpt b/Zend/tests/ghsa-rwp7-7vc6-8477_001.phpt new file mode 100644 index 0000000000000..d0e9ddcba410b --- /dev/null +++ b/Zend/tests/ghsa-rwp7-7vc6-8477_001.phpt @@ -0,0 +1,26 @@ +--TEST-- +GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation +--FILE-- +foo()->baz ??= 1; +} catch (Exception $e) { + echo $e->getMessage(); +} + +?> +--EXPECT-- +Hello diff --git a/Zend/tests/ghsa-rwp7-7vc6-8477_002.phpt b/Zend/tests/ghsa-rwp7-7vc6-8477_002.phpt new file mode 100644 index 0000000000000..4115d9eae26fd --- /dev/null +++ b/Zend/tests/ghsa-rwp7-7vc6-8477_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation +--FILE-- +foo()->prop ??= 'foo'; +} catch (Error $e) { + echo $e->getMessage(); +} + +?> +--EXPECT-- +Cannot assign string to property Foo::$prop of type int diff --git a/Zend/tests/ghsa-rwp7-7vc6-8477_003.phpt b/Zend/tests/ghsa-rwp7-7vc6-8477_003.phpt new file mode 100644 index 0000000000000..f2808afbf84de --- /dev/null +++ b/Zend/tests/ghsa-rwp7-7vc6-8477_003.phpt @@ -0,0 +1,22 @@ +--TEST-- +GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation +--FILE-- +prop ??= 'foo'; +} catch (Error $e) { + echo $e->getMessage(); +} + +?> +--EXPECT-- +Cannot assign string to property Foo::$prop of type int diff --git a/Zend/tests/lazy_objects/gh17941.phpt b/Zend/tests/lazy_objects/gh17941.phpt new file mode 100644 index 0000000000000..6af6355b99573 --- /dev/null +++ b/Zend/tests/lazy_objects/gh17941.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-17941 (Stack-use-after-return with lazy objects and hooks) +--FILE-- + $this->prop; set($x) => $this->prop = $x;} +} + +$rc = new ReflectionClass(SubClass::class); +$obj = $rc->newLazyProxy(function ($object) { + echo "init\n"; + return new SubClass; +}); + +function foo(SubClass $x) { + $x->prop = 1; + var_dump($x->prop); +} + +foo($obj); + +?> +--EXPECT-- +init +int(1) diff --git a/Zend/tests/lazy_objects/gh17998.phpt b/Zend/tests/lazy_objects/gh17998.phpt new file mode 100644 index 0000000000000..12d22b4704a13 --- /dev/null +++ b/Zend/tests/lazy_objects/gh17998.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-17998: Skipped lazy init on primed SIMPLE_WRITE +--FILE-- + $value; + } +} + +$nonLazy = new C; + +$lazy = (new ReflectionClass(C::class))->newLazyProxy(function () { + echo "init\n"; + return new C; +}); + +function foo(C $c) { + $c->prop = 1; + var_dump($c->prop); +} + +foo($nonLazy); +foo($lazy); + +?> +--EXPECT-- +int(1) +init +int(1) diff --git a/Zend/tests/oss-fuzz-403816122.phpt b/Zend/tests/oss-fuzz-403816122.phpt new file mode 100644 index 0000000000000..b9d9400609fc6 --- /dev/null +++ b/Zend/tests/oss-fuzz-403816122.phpt @@ -0,0 +1,22 @@ +--TEST-- +OSS-Fuzz #403816122: Segfault when initializing default properties of child prop with added hooks +--FILE-- + 'y'; + } +} + +var_dump((new C)->prop); + +?> +--EXPECT-- +string(1) "y" diff --git a/Zend/tests/property_hooks/default_value_inheritance.phpt b/Zend/tests/property_hooks/default_value_inheritance.phpt new file mode 100644 index 0000000000000..3821e19634e76 --- /dev/null +++ b/Zend/tests/property_hooks/default_value_inheritance.phpt @@ -0,0 +1,54 @@ +--TEST-- +Property default values are not inherited +--FILE-- + parent::$a::get(); } + public int $b { get => parent::$b::get(); } + public $c = 2 { get => parent::$c::get(); } + public int $d = 2 { get => parent::$d::get(); } +} + +class GC extends C { + public $a { get => parent::$a::get(); } + public int $b { get => parent::$b::get(); } + public $c { get => parent::$c::get(); } + public int $d { get => parent::$d::get(); } +} + +function test(P $p) { + var_dump($p->a); + try { + var_dump($p->b); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + var_dump($p->c); + try { + var_dump($p->d); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } +} + +test(new C); +test(new GC); + +?> +--EXPECT-- +NULL +Typed property C::$b must not be accessed before initialization +int(2) +int(2) +NULL +Typed property GC::$b must not be accessed before initialization +NULL +Typed property GC::$d must not be accessed before initialization diff --git a/Zend/tests/property_hooks/dump.phpt b/Zend/tests/property_hooks/dump.phpt index d7cd57183d63f..84db6cb3175b0 100644 --- a/Zend/tests/property_hooks/dump.phpt +++ b/Zend/tests/property_hooks/dump.phpt @@ -34,7 +34,7 @@ class Test { } class Child extends Test { - public $addedHooks { + public $addedHooks = 'addedHooks' { get { return strtoupper(parent::$addedHooks::get()); } } private $changed = 'changed Child' { diff --git a/Zend/tests/property_hooks/generator_hook_002.phpt b/Zend/tests/property_hooks/generator_hook_002.phpt index 0eeb99c8cf9b4..5945720c340d2 100644 --- a/Zend/tests/property_hooks/generator_hook_002.phpt +++ b/Zend/tests/property_hooks/generator_hook_002.phpt @@ -8,7 +8,7 @@ class A { } class B extends A { - public $prop { + public $prop = 42 { get { yield parent::$prop::get() + 1; yield parent::$prop::get() + 2; diff --git a/Zend/tests/property_hooks/gh17376.phpt b/Zend/tests/property_hooks/gh17376.phpt new file mode 100644 index 0000000000000..d0896ff4599e4 --- /dev/null +++ b/Zend/tests/property_hooks/gh17376.phpt @@ -0,0 +1,119 @@ +--TEST-- +GH-17376: Child classes may add hooks to plain properties +--INI-- +# Avoid triggering for main, trigger for test so we get a side-trace for property hooks +opcache.jit_hot_func=2 +--FILE-- +prop; + } + set { + echo __METHOD__, "\n"; + $this->prop = $value; + } + } +} + +function test(A $a) { + echo "read\n"; + var_dump($a->prop); + echo "write\n"; + $a->prop = 42; + echo "read-write\n"; + $a->prop += 43; + echo "pre-inc\n"; + ++$a->prop; + echo "pre-dec\n"; + --$a->prop; + echo "post-inc\n"; + $a->prop++; + echo "post-dec\n"; + $a->prop--; +} + +echo "A\n"; +test(new A); + +echo "\nA\n"; +test(new A); + +echo "\nB\n"; +test(new B); + +echo "\nB\n"; +test(new B); + +?> +--EXPECT-- +A +read +int(1) +write +read-write +pre-inc +pre-dec +post-inc +post-dec + +A +read +int(1) +write +read-write +pre-inc +pre-dec +post-inc +post-dec + +B +read +B::$prop::get +int(1) +write +B::$prop::set +read-write +B::$prop::get +B::$prop::set +pre-inc +B::$prop::get +B::$prop::set +pre-dec +B::$prop::get +B::$prop::set +post-inc +B::$prop::get +B::$prop::set +post-dec +B::$prop::get +B::$prop::set + +B +read +B::$prop::get +int(1) +write +B::$prop::set +read-write +B::$prop::get +B::$prop::set +pre-inc +B::$prop::get +B::$prop::set +pre-dec +B::$prop::get +B::$prop::set +post-inc +B::$prop::get +B::$prop::set +post-dec +B::$prop::get +B::$prop::set diff --git a/Zend/tests/property_hooks/gh17988.phpt b/Zend/tests/property_hooks/gh17988.phpt new file mode 100644 index 0000000000000..629eec60d010b --- /dev/null +++ b/Zend/tests/property_hooks/gh17988.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-17988: Incorrect handling of hooked properties without get hook in get_object_vars() +--FILE-- + $value; + } +} + +$c = new C; +$c->prop = 42; + +var_dump($c); +var_dump(get_object_vars($c)); +var_export($c); +echo "\n"; +var_dump(json_encode($c)); +var_dump((array)$c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + string(2) "42" +} +array(1) { + ["prop"]=> + string(2) "42" +} +\C::__set_state(array( + 'prop' => '42', +)) +string(13) "{"prop":"42"}" +array(1) { + ["prop"]=> + string(2) "42" +} diff --git a/Zend/tests/property_hooks/gh18000.phpt b/Zend/tests/property_hooks/gh18000.phpt new file mode 100644 index 0000000000000..61b36034671f9 --- /dev/null +++ b/Zend/tests/property_hooks/gh18000.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-18000: Lazy proxy calls set hook twice +--FILE-- +prop = $value * 2; + } + } +} + +$rc = new ReflectionClass(C::class); + +$obj = $rc->newLazyProxy(function () { + echo "init\n"; + return new C; +}); + +function foo(C $c) { + $c->prop = 1; + var_dump($c->prop); +} + +foo($obj); + +?> +--EXPECT-- +set +init +int(2) diff --git a/Zend/tests/property_hooks/multi_level_inheritance.phpt b/Zend/tests/property_hooks/multi_level_inheritance.phpt new file mode 100644 index 0000000000000..a41a32fd71fd5 --- /dev/null +++ b/Zend/tests/property_hooks/multi_level_inheritance.phpt @@ -0,0 +1,70 @@ +--TEST-- +Property hooks with multi level inheritance +--FILE-- + parent::$prop::get() * 2; } +} + +class C extends B { + public $prop = 3; +} + +function test(A $a) { + var_dump($a); + var_dump((array)$a); + var_dump(unserialize(serialize($a))); + var_dump(get_object_vars($a)); + var_dump(json_decode(json_encode($a))); +} + +test(new B); +test(new C); + +?> +--EXPECTF-- +object(B)#%d (1) { + ["prop"]=> + int(2) +} +array(1) { + ["prop"]=> + int(2) +} +object(B)#%d (1) { + ["prop"]=> + int(2) +} +array(1) { + ["prop"]=> + int(4) +} +object(stdClass)#%d (1) { + ["prop"]=> + int(4) +} +object(C)#%d (1) { + ["prop"]=> + int(3) +} +array(1) { + ["prop"]=> + int(3) +} +object(C)#%d (1) { + ["prop"]=> + int(3) +} +array(1) { + ["prop"]=> + int(6) +} +object(stdClass)#%d (1) { + ["prop"]=> + int(6) +} diff --git a/Zend/tests/property_hooks/oss_fuzz_403308724.phpt b/Zend/tests/property_hooks/oss_fuzz_403308724.phpt new file mode 100644 index 0000000000000..b27b08dd703b6 --- /dev/null +++ b/Zend/tests/property_hooks/oss_fuzz_403308724.phpt @@ -0,0 +1,30 @@ +--TEST-- +OSS-Fuzz #403308724 +--FILE-- + 1; } +} + +class Test extends Base { + public $y { + get => [new class { + public $inner {get => __PROPERTY__;} + }, parent::$y::get()]; + } +} + +$test = new Test; +$y = $test->y; +var_dump($y); +var_dump($y[0]->inner); +?> +--EXPECT-- +array(2) { + [0]=> + object(class@anonymous)#2 (0) { + } + [1]=> + int(1) +} +string(5) "inner" diff --git a/Zend/tests/property_hooks/parent_get_plain.phpt b/Zend/tests/property_hooks/parent_get_plain.phpt index f461b39a8a372..c3dc72d51fee8 100644 --- a/Zend/tests/property_hooks/parent_get_plain.phpt +++ b/Zend/tests/property_hooks/parent_get_plain.phpt @@ -8,7 +8,7 @@ class P { } class C extends P { - public $prop { + public $prop = 42 { get => parent::$prop::get(); } } diff --git a/Zend/zend.h b/Zend/zend.h index 79b4b468d7409..1c352860393b3 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.4.5-dev" +#define ZEND_VERSION "4.4.6" #define ZEND_ENGINE_3 diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 8c239a952f32b..5aac3c1f7d77c 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -22,6 +22,7 @@ #include "zend.h" #include "zend_execute.h" #include "zend_API.h" +#include "zend_hash.h" #include "zend_modules.h" #include "zend_extensions.h" #include "zend_constants.h" @@ -1612,8 +1613,12 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) / /* Use the default properties table to also update initializers of private properties * that have been shadowed in a child class. */ for (uint32_t i = 0; i < class_type->default_properties_count; i++) { - val = &default_properties_table[i]; prop_info = class_type->properties_info_table[i]; + if (!prop_info) { + continue; + } + + val = &default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; if (Z_TYPE_P(val) == IS_CONSTANT_AST && UNEXPECTED(update_property(val, prop_info) != SUCCESS)) { return FAILURE; @@ -3263,21 +3268,17 @@ ZEND_API zend_result zend_get_module_started(const char *module_name) /* {{{ */ } /* }}} */ -static int clean_module_class(zval *el, void *arg) /* {{{ */ -{ - zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el); - int module_number = *(int *)arg; - if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) { - return ZEND_HASH_APPLY_REMOVE; - } else { - return ZEND_HASH_APPLY_KEEP; - } -} -/* }}} */ - static void clean_module_classes(int module_number) /* {{{ */ { - zend_hash_apply_with_argument(EG(class_table), clean_module_class, (void *) &module_number); + /* Child classes may reuse structures from parent classes, so destroy in reverse order. */ + Bucket *bucket; + ZEND_HASH_REVERSE_FOREACH_BUCKET(EG(class_table), bucket) { + zend_class_entry *ce = Z_CE(bucket->val); + if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) { + zend_hash_del_bucket(EG(class_table), bucket); + } + } ZEND_HASH_FOREACH_END(); + } /* }}} */ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index f2f6b80fc66d7..8ed7939200c79 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -840,7 +840,7 @@ ZEND_FUNCTION(get_object_vars) } const char *unmangled_name_cstr = zend_get_unmangled_property_name(prop_info->name); zend_string *unmangled_name = zend_string_init(unmangled_name_cstr, strlen(unmangled_name_cstr), false); - zend_read_property_ex(prop_info->ce, zobj, unmangled_name, /* silent */ true, &tmp); + value = zend_read_property_ex(prop_info->ce, zobj, unmangled_name, /* silent */ true, &tmp); zend_string_release_ex(unmangled_name, false); if (EG(exception)) { zend_release_properties(properties); @@ -848,7 +848,6 @@ ZEND_FUNCTION(get_object_vars) ZVAL_UNDEF(return_value); RETURN_THROWS(); } - value = &tmp; } Z_TRY_ADDREF_P(value); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 049c026845b1c..6ad2f6ac40246 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -361,11 +361,12 @@ static zend_result zend_create_closure_from_callable(zval *return_value, zval *c memset(&call, 0, sizeof(zend_internal_function)); call.type = ZEND_INTERNAL_FUNCTION; - call.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC; + call.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_DEPRECATED); call.handler = zend_closure_call_magic; call.function_name = mptr->common.function_name; call.scope = mptr->common.scope; call.doc_comment = NULL; + call.attributes = mptr->common.attributes; zend_free_trampoline(mptr); mptr = (zend_function *) &call; @@ -871,7 +872,7 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* { memset(&trampoline, 0, sizeof(zend_internal_function)); trampoline.type = ZEND_INTERNAL_FUNCTION; - trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE); + trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE | ZEND_ACC_DEPRECATED); trampoline.handler = zend_closure_call_magic; trampoline.function_name = mptr->common.function_name; trampoline.scope = mptr->common.scope; @@ -879,6 +880,7 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* { if (trampoline.fn_flags & ZEND_ACC_VARIADIC) { trampoline.arg_info = trampoline_arg_info; } + trampoline.attributes = mptr->common.attributes; zend_free_trampoline(mptr); mptr = (zend_function *) &trampoline; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ef75b45ad0528..832dedc421042 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8645,7 +8645,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f /* FIXME: This is a dirty fix to maintain ABI compatibility. We don't * have an actual property info yet, but we really only need the name * anyway. We should convert this to a zend_string. */ - ZEND_ASSERT(!CG(context).active_property_info); + const zend_property_info *old_active_property_info = CG(context).active_property_info; zend_property_info dummy_prop_info = { .name = name }; CG(context).active_property_info = &dummy_prop_info; @@ -8742,7 +8742,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f zend_compile_attributes(&info->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, 0); } - CG(context).active_property_info = NULL; + CG(context).active_property_info = old_active_property_info; } } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1eaf3ef686e79..7f425852d01b4 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -463,7 +463,7 @@ typedef struct _zend_property_info { #define OBJ_PROP_TO_OFFSET(num) \ ((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num))) #define OBJ_PROP_TO_NUM(offset) \ - ((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) + (((offset) - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) typedef struct _zend_class_constant { zval value; /* flags are stored in u2 */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0f8b062e3f046..f5399ad28dcb2 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3424,6 +3424,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c return; } } + } else if (prop_op_type == IS_CONST) { + /* CE mismatch, make cache slot consistent */ + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; } /* Pointer on property callback is required */ diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index a966a106def33..f73fef50e16bb 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1917,7 +1917,7 @@ ZEND_API int zend_gc_collect_cycles(void) bool did_rerun_gc = 0; zend_hrtime_t start_time = zend_hrtime(); - if (GC_G(num_roots) && GC_G(gc_active)) { + if (GC_G(num_roots) && !GC_G(gc_active)) { zend_gc_remove_root_tmpvars(); } diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 9a1314682cee6..b1ed8e4b61675 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1436,7 +1436,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke } if (!(parent_info->flags & ZEND_ACC_PRIVATE)) { if (!(parent_info->ce->ce_flags & ZEND_ACC_INTERFACE)) { - child_info->prototype = parent_info; + child_info->prototype = parent_info->prototype; } if (UNEXPECTED((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC))) { @@ -1478,17 +1478,44 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ZSTR_VAL(ce->name), ZSTR_VAL(key), zend_visibility_string(parent_info->flags), ZSTR_VAL(parent_info->ce->name), (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } if (!(child_info->flags & ZEND_ACC_STATIC) && !(parent_info->flags & ZEND_ACC_VIRTUAL)) { - if (child_info->offset != ZEND_VIRTUAL_PROPERTY_OFFSET) { - int parent_num = OBJ_PROP_TO_NUM(parent_info->offset); - int child_num = OBJ_PROP_TO_NUM(child_info->offset); + /* If we added hooks to the child property, we use the child's slot for + * storage to keep the parent slot set to IS_UNDEF. This automatically + * picks the slow path in the JIT. */ + bool use_child_prop = !parent_info->hooks && child_info->hooks; + + if (use_child_prop && child_info->offset == ZEND_VIRTUAL_PROPERTY_OFFSET) { + child_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count); + ce->default_properties_count++; + ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS); + zval *property_default_ptr = &ce->default_properties_table[OBJ_PROP_TO_NUM(child_info->offset)]; + ZVAL_UNDEF(property_default_ptr); + Z_PROP_FLAG_P(property_default_ptr) = IS_PROP_UNINIT; + } + int parent_num = OBJ_PROP_TO_NUM(parent_info->offset); + if (child_info->offset != ZEND_VIRTUAL_PROPERTY_OFFSET) { /* Don't keep default properties in GC (they may be freed by opcache) */ zval_ptr_dtor_nogc(&(ce->default_properties_table[parent_num])); - ce->default_properties_table[parent_num] = ce->default_properties_table[child_num]; - ZVAL_UNDEF(&ce->default_properties_table[child_num]); + + if (use_child_prop) { + ZVAL_UNDEF(&ce->default_properties_table[parent_num]); + } else { + int child_num = OBJ_PROP_TO_NUM(child_info->offset); + ce->default_properties_table[parent_num] = ce->default_properties_table[child_num]; + ZVAL_UNDEF(&ce->default_properties_table[child_num]); + } + } else { + /* Default value was removed in child, remove it from parent too. */ + if (ZEND_TYPE_IS_SET(child_info->type)) { + ZVAL_UNDEF(&ce->default_properties_table[parent_num]); + } else { + ZVAL_NULL(&ce->default_properties_table[parent_num]); + } } - child_info->offset = parent_info->offset; + if (!use_child_prop) { + child_info->offset = parent_info->offset; + } child_info->flags &= ~ZEND_ACC_VIRTUAL; } @@ -1663,7 +1690,8 @@ void zend_build_properties_info_table(zend_class_entry *ce) ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { if (prop->ce == ce && (prop->flags & ZEND_ACC_STATIC) == 0 && !(prop->flags & ZEND_ACC_VIRTUAL)) { - table[OBJ_PROP_TO_NUM(prop->offset)] = prop; + uint32_t prop_table_offset = OBJ_PROP_TO_NUM(!(prop->prototype->flags & ZEND_ACC_VIRTUAL) ? prop->prototype->offset : prop->offset); + table[prop_table_offset] = prop; } } ZEND_HASH_FOREACH_END(); } @@ -1677,8 +1705,12 @@ ZEND_API void zend_verify_hooked_property(zend_class_entry *ce, zend_property_in /* We specified a default value (otherwise offset would be -1), but the virtual flag wasn't * removed during inheritance. */ if ((prop_info->flags & ZEND_ACC_VIRTUAL) && prop_info->offset != ZEND_VIRTUAL_PROPERTY_OFFSET) { - zend_error_noreturn(E_COMPILE_ERROR, - "Cannot specify default value for virtual hooked property %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(prop_name)); + if (Z_TYPE(ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]) == IS_UNDEF) { + prop_info->offset = ZEND_VIRTUAL_PROPERTY_OFFSET; + } else { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot specify default value for virtual hooked property %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(prop_name)); + } } /* If the property turns backed during inheritance and no type and default value are set, we want * the default value to be null. */ diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index e6dd6144d4b5c..d1b950160e1cc 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -268,14 +268,17 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, obj = zend_objects_new(reflection_ce); - for (int i = 0; i < obj->ce->default_properties_count; i++) { + /* Iterate in reverse to avoid overriding Z_PROP_FLAG_P() of child props with added hooks (GH-17870). */ + for (int i = obj->ce->default_properties_count - 1; i >= 0; i--) { zval *p = &obj->properties_table[i]; ZVAL_UNDEF(p); - if (EXPECTED(obj->ce->properties_info_table[i])) { + Z_PROP_FLAG_P(p) = 0; + + zend_property_info *prop_info = obj->ce->properties_info_table[i]; + if (prop_info) { + zval *p = &obj->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; lazy_properties_count++; - } else { - Z_PROP_FLAG_P(p) = 0; } } } else { @@ -326,7 +329,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, for (int i = 0; i < reflection_ce->default_properties_count; i++) { zend_property_info *prop_info = obj->ce->properties_info_table[i]; if (EXPECTED(prop_info)) { - zval *p = &obj->properties_table[i]; + zval *p = &obj->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; if (Z_TYPE_P(p) != IS_UNDEF) { if ((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(p) & IS_PROP_REINITABLE) /* TODO: test final property */ @@ -408,12 +411,16 @@ static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_tabl zval *properties_table = obj->properties_table; for (int i = 0; i < ce->default_properties_count; i++) { - zval *p = &properties_table[i]; + zend_property_info *prop_info = ce->properties_info_table[i]; + if (!prop_info) { + continue; + } + + zval *p = &properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; zend_object_dtor_property(obj, p); - ZVAL_COPY_VALUE_PROP(p, &properties_table_snapshot[i]); + ZVAL_COPY_VALUE_PROP(p, &properties_table_snapshot[OBJ_PROP_TO_NUM(prop_info->offset)]); - zend_property_info *prop_info = ce->properties_info_table[i]; - if (Z_ISREF_P(p) && prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { + if (Z_ISREF_P(p) && ZEND_TYPE_IS_SET(prop_info->type)) { ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(p), prop_info); } } @@ -526,10 +533,12 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) obj->properties = NULL; for (int i = 0; i < Z_OBJ(retval)->ce->default_properties_count; i++) { - if (EXPECTED(Z_OBJ(retval)->ce->properties_info_table[i])) { - zend_object_dtor_property(obj, &obj->properties_table[i]); - ZVAL_UNDEF(&obj->properties_table[i]); - Z_PROP_FLAG_P(&obj->properties_table[i]) = IS_PROP_UNINIT | IS_PROP_LAZY; + zend_property_info *prop_info = Z_OBJ(retval)->ce->properties_info_table[i]; + if (EXPECTED(prop_info)) { + zval *prop = &obj->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; + zend_object_dtor_property(obj, prop); + ZVAL_UNDEF(prop); + Z_PROP_FLAG_P(prop) = IS_PROP_UNINIT | IS_PROP_LAZY; } } @@ -722,13 +731,16 @@ zend_object *zend_lazy_object_clone(zend_object *old_obj) zend_class_entry *ce = old_obj->ce; zend_object *new_proxy = zend_objects_new(ce); - for (int i = 0; i < ce->default_properties_count; i++) { + /* Iterate in reverse to avoid overriding Z_PROP_FLAG_P() of child props with added hooks (GH-17870). */ + for (int i = ce->default_properties_count - 1; i >= 0; i--) { zval *p = &new_proxy->properties_table[i]; ZVAL_UNDEF(p); - if (EXPECTED(ce->properties_info_table[i])) { + Z_PROP_FLAG_P(p) = 0; + + zend_property_info *prop_info = ce->properties_info_table[i]; + if (prop_info) { + zval *p = &new_proxy->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; - } else { - Z_PROP_FLAG_P(p) = 0; } } @@ -806,7 +818,11 @@ zend_property_info *zend_lazy_object_get_property_info_for_slot(zend_object *obj zend_property_info **table = obj->ce->properties_info_table; intptr_t prop_num = slot - obj->properties_table; if (prop_num >= 0 && prop_num < obj->ce->default_properties_count) { - return table[prop_num]; + if (table[prop_num]) { + return table[prop_num]; + } else { + return zend_get_property_info_for_slot_slow(obj, slot); + } } if (!zend_lazy_object_initialized(obj)) { diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 5a4e4b3ea3a1c..a4dba771e3ef5 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -673,9 +673,23 @@ static bool zend_is_in_hook(const zend_property_info *prop_info) static bool zend_should_call_hook(const zend_property_info *prop_info, const zend_object *obj) { - return !zend_is_in_hook(prop_info) - /* execute_data and This are guaranteed to be set if zend_is_in_hook() returns true. */ - || Z_OBJ(EG(current_execute_data)->This) != obj; + if (!zend_is_in_hook(prop_info)) { + return true; + } + + /* execute_data and This are guaranteed to be set if zend_is_in_hook() returns true. */ + zend_object *parent_obj = Z_OBJ(EG(current_execute_data)->This); + if (parent_obj == obj) { + return false; + } + + if (zend_object_is_lazy_proxy(parent_obj) + && zend_lazy_object_initialized(parent_obj) + && zend_lazy_object_get_instance(parent_obj) == obj) { + return false; + } + + return true; } static ZEND_COLD void zend_throw_no_prop_backing_value_access(zend_string *class_name, zend_string *prop_name, bool is_read) @@ -1198,6 +1212,11 @@ lazy_init:; variable_ptr = zend_std_write_property(zobj, name, &backup, cache_slot); zval_ptr_dtor(&backup); + + if (variable_ptr == &backup) { + variable_ptr = value; + } + return variable_ptr; } /* }}} */ diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 8a6b714c8b3fd..1ba250bec6439 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -200,3 +200,15 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ * } } /* }}} */ + +ZEND_API ZEND_COLD zend_property_info *zend_get_property_info_for_slot_slow(zend_object *obj, zval *slot) +{ + uintptr_t offset = (uintptr_t)slot - (uintptr_t)obj->properties_table; + zend_property_info *prop_info; + ZEND_HASH_MAP_FOREACH_PTR(&obj->ce->properties_info, prop_info) { + if (prop_info->offset == offset) { + return prop_info; + } + } ZEND_HASH_FOREACH_END(); + return NULL; +} diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index 02326f2b31460..242bf212ba9c6 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -96,6 +96,8 @@ static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_en return obj; } +ZEND_API ZEND_COLD zend_property_info *zend_get_property_info_for_slot_slow(zend_object *obj, zval *slot); + /* Use when 'slot' was obtained directly from obj->properties_table, or when * 'obj' can not be lazy. Otherwise, use zend_get_property_info_for_slot(). */ static inline zend_property_info *zend_get_property_info_for_slot_self(zend_object *obj, zval *slot) @@ -103,7 +105,11 @@ static inline zend_property_info *zend_get_property_info_for_slot_self(zend_obje zend_property_info **table = obj->ce->properties_info_table; intptr_t prop_num = slot - obj->properties_table; ZEND_ASSERT(prop_num >= 0 && prop_num < obj->ce->default_properties_count); - return table[prop_num]; + if (table[prop_num]) { + return table[prop_num]; + } else { + return zend_get_property_info_for_slot_slow(obj, slot); + } } static inline zend_property_info *zend_get_property_info_for_slot(zend_object *obj, zval *slot) @@ -114,7 +120,11 @@ static inline zend_property_info *zend_get_property_info_for_slot(zend_object *o zend_property_info **table = obj->ce->properties_info_table; intptr_t prop_num = slot - obj->properties_table; ZEND_ASSERT(prop_num >= 0 && prop_num < obj->ce->default_properties_count); - return table[prop_num]; + if (table[prop_num]) { + return table[prop_num]; + } else { + return zend_get_property_info_for_slot_slow(obj, slot); + } } /* Helper for cases where we're only interested in property info of typed properties. */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 12c2759656b2d..f32ae13e06793 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -940,6 +940,14 @@ static void zend_calc_live_ranges( opnum--; opline--; + /* SEPARATE always redeclares its op1. For the purposes of live-ranges, + * its declaration is irrelevant. Don't terminate the current live-range + * to avoid breaking special handling of COPY_TMP. */ + if (opline->opcode == ZEND_SEPARATE) { + ZEND_ASSERT(opline->op1.var == opline->result.var); + continue; + } + if ((opline->result_type & (IS_TMP_VAR|IS_VAR)) && !is_fake_def(opline)) { uint32_t var_num = EX_VAR_TO_NUM(opline->result.var) - var_offset; /* Defs without uses can occur for two reasons: Either because the result is diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index eea3a4f7e2da1..a4fa8063a5bd4 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2450,12 +2450,14 @@ ZEND_VM_C_LABEL(assign_object): void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +ZEND_VM_C_LABEL(assign_obj_simple): property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); ZEND_VM_C_GOTO(free_and_exit_assign_obj); @@ -2527,14 +2529,12 @@ ZEND_VM_C_LABEL(fast_assign_obj): } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - ZEND_VM_C_GOTO(free_and_exit_assign_obj); - } else { - ZEND_VM_C_GOTO(fast_assign_obj); + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + ZEND_VM_C_GOTO(assign_obj_simple); } /* Fall through to write_property for hooks. */ } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cb4f3747a02b0..2f6f0af2d872c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -24037,12 +24037,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24114,14 +24116,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -24191,12 +24191,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24268,14 +24270,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -24345,12 +24345,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24422,14 +24424,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -24499,12 +24499,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24576,14 +24578,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27028,12 +27028,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27105,14 +27107,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27182,12 +27182,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27259,14 +27261,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27336,12 +27336,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27413,14 +27415,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27490,12 +27490,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27567,14 +27569,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31381,12 +31381,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31458,14 +31460,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31535,12 +31535,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31612,14 +31614,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31689,12 +31689,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31766,14 +31768,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31843,12 +31843,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31920,14 +31922,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34128,12 +34128,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34205,14 +34207,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34282,12 +34282,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34359,14 +34361,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34436,12 +34436,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34513,14 +34515,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34590,12 +34590,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34667,14 +34669,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36296,12 +36296,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36373,14 +36375,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36450,12 +36450,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36527,14 +36529,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36604,12 +36604,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36681,14 +36683,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36758,12 +36758,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36835,14 +36837,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -38942,12 +38942,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39019,14 +39021,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -39096,12 +39096,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39173,14 +39175,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -39250,12 +39250,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39327,14 +39329,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -39404,12 +39404,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39481,14 +39483,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43342,12 +43342,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43419,14 +43421,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43496,12 +43496,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43573,14 +43575,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43650,12 +43650,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43727,14 +43729,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43804,12 +43804,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43881,14 +43883,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47294,12 +47294,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47371,14 +47373,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47448,12 +47448,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47525,14 +47527,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47602,12 +47602,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47679,14 +47681,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47756,12 +47756,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47833,14 +47835,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -52793,12 +52793,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -52870,14 +52872,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -52947,12 +52947,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -53024,14 +53026,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -53101,12 +53101,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -53178,14 +53180,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -53255,12 +53255,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -53332,14 +53334,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 7f503e78e2935..c94cd6b616e43 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -2416,6 +2416,12 @@ function gen_vm($def, $skel) { $max_opcode = 0; $extra_num = 256; foreach ($in as $line) { + // Handle Windows line endings, GH-17836; since a bunch of regular + // expressions below test for a newline at the end, just update the + // ending + if (substr($line, -2) === "\r\n") { + $line = substr_replace($line, "\n", -2); + } ++$lineno; if (strpos($line,"ZEND_VM_HANDLER(") === 0 || strpos($line,"ZEND_VM_INLINE_HANDLER(") === 0 || diff --git a/build/Makefile.global b/build/Makefile.global index 37b48ba2980ea..d5170ebcae4ac 100644 --- a/build/Makefile.global +++ b/build/Makefile.global @@ -18,6 +18,10 @@ libphp.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(LIBTOOL) --tag=CC --mode=link $(CC) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ -@$(LIBTOOL) --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1 +libphp.dylib: libphp.la + $(LIBTOOL) --tag=CC --mode=link $(CC) -dynamiclib $(LIBPHP_CFLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -rpath $(phptempdir) -install_name @rpath/$@ $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ + -@$(LIBTOOL) --silent --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1 + libs/libphp.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp.so diff --git a/build/php.m4 b/build/php.m4 index e45b22b7665fc..d8a5cbf084293 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -779,6 +779,14 @@ AC_DEFUN([PHP_BUILD_SHARED],[ php_lo=$shared_lo ]) +dnl +dnl PHP_BUILD_SHARED_DYLIB +dnl +AC_DEFUN([PHP_BUILD_SHARED_DYLIB],[ + PHP_BUILD_SHARED + OVERALL_TARGET=libphp.dylib +]) + dnl dnl PHP_BUILD_STATIC dnl @@ -894,6 +902,7 @@ AC_DEFUN([PHP_SELECT_SAPI],[ case "$2" in static[)] PHP_BUILD_STATIC;; shared[)] PHP_BUILD_SHARED;; + shared-dylib[)] PHP_BUILD_SHARED_DYLIB;; bundle[)] PHP_BUILD_BUNDLE;; esac install_sapi="install-sapi" diff --git a/configure.ac b/configure.ac index 6e06e6e799541..8e04a1717f2a7 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.4.5-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) +AC_INIT([PHP],[8.4.6],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c index 79c1d4216fe7b..bd9a44a240503 100644 --- a/ext/bcmath/libbcmath/src/str2num.c +++ b/ext/bcmath/libbcmath/src/str2num.c @@ -180,7 +180,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz */ if (str_scale > 0) { const char *fractional_new_end = bc_skip_zero_reverse(fractional_end, fractional_ptr); - str_scale -= fractional_new_end - fractional_end; + str_scale -= fractional_end - fractional_new_end; /* fractional_end >= fractional_new_end */ } } } else { diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h index 3c75462009afb..a4cbb618799c8 100644 --- a/ext/date/lib/timezonedb.h +++ b/ext/date/lib/timezonedb.h @@ -4,7 +4,7 @@ #endif #ifdef TIMELIB_SUPPORT_SLIM_FILE -const timelib_tzdb_index_entry timezonedb_idx_builtin[597] = { +const timelib_tzdb_index_entry timezonedb_idx_builtin[598] = { { (char*) "Africa/Abidjan" , 0x000000 }, { (char*) "Africa/Accra" , 0x00008E }, { (char*) "Africa/Addis_Ababa" , 0x000356 }, @@ -104,508 +104,509 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[597] = { { (char*) "America/Coral_Harbour" , 0x00ADD3 }, { (char*) "America/Cordoba" , 0x00AE74 }, { (char*) "America/Costa_Rica" , 0x00B144 }, - { (char*) "America/Creston" , 0x00B238 }, - { (char*) "America/Cuiaba" , 0x00B2F4 }, - { (char*) "America/Curacao" , 0x00B6B1 }, - { (char*) "America/Danmarkshavn" , 0x00B754 }, - { (char*) "America/Dawson" , 0x00B939 }, - { (char*) "America/Dawson_Creek" , 0x00BD5C }, - { (char*) "America/Denver" , 0x00C033 }, - { (char*) "America/Detroit" , 0x00C466 }, - { (char*) "America/Dominica" , 0x00C80E }, - { (char*) "America/Edmonton" , 0x00C89C }, - { (char*) "America/Eirunepe" , 0x00CC94 }, - { (char*) "America/El_Salvador" , 0x00CE63 }, - { (char*) "America/Ensenada" , 0x00CF1F }, - { (char*) "America/Fort_Nelson" , 0x00D362 }, - { (char*) "America/Fort_Wayne" , 0x00D92A }, - { (char*) "America/Fortaleza" , 0x00DB49 }, - { (char*) "America/Glace_Bay" , 0x00DD5F }, - { (char*) "America/Godthab" , 0x00E0F6 }, - { (char*) "America/Goose_Bay" , 0x00E4C7 }, - { (char*) "America/Grand_Turk" , 0x00EB1F }, - { (char*) "America/Grenada" , 0x00EE80 }, - { (char*) "America/Guadeloupe" , 0x00EF0E }, - { (char*) "America/Guatemala" , 0x00EF9C }, - { (char*) "America/Guayaquil" , 0x00F07C }, - { (char*) "America/Guyana" , 0x00F14D }, - { (char*) "America/Halifax" , 0x00F20E }, - { (char*) "America/Havana" , 0x00F8C0 }, - { (char*) "America/Hermosillo" , 0x00FD29 }, - { (char*) "America/Indiana/Indianapolis" , 0x00FE3D }, - { (char*) "America/Indiana/Knox" , 0x010075 }, - { (char*) "America/Indiana/Marengo" , 0x01048E }, - { (char*) "America/Indiana/Petersburg" , 0x0106E8 }, - { (char*) "America/Indiana/Tell_City" , 0x0109B2 }, - { (char*) "America/Indiana/Vevay" , 0x010BDC }, - { (char*) "America/Indiana/Vincennes" , 0x010D73 }, - { (char*) "America/Indiana/Winamac" , 0x010FC9 }, - { (char*) "America/Indianapolis" , 0x011246 }, - { (char*) "America/Inuvik" , 0x011465 }, - { (char*) "America/Iqaluit" , 0x0117B6 }, - { (char*) "America/Jamaica" , 0x011B32 }, - { (char*) "America/Jujuy" , 0x011C91 }, - { (char*) "America/Juneau" , 0x011F4F }, - { (char*) "America/Kentucky/Louisville" , 0x012335 }, - { (char*) "America/Kentucky/Monticello" , 0x012839 }, - { (char*) "America/Knox_IN" , 0x012C25 }, - { (char*) "America/Kralendijk" , 0x013029 }, - { (char*) "America/La_Paz" , 0x0130E6 }, - { (char*) "America/Lima" , 0x01319C }, - { (char*) "America/Los_Angeles" , 0x0132C3 }, - { (char*) "America/Louisville" , 0x0137E4 }, - { (char*) "America/Lower_Princes" , 0x013CCA }, - { (char*) "America/Maceio" , 0x013D87 }, - { (char*) "America/Managua" , 0x013F99 }, - { (char*) "America/Manaus" , 0x0140CC }, - { (char*) "America/Marigot" , 0x014283 }, - { (char*) "America/Martinique" , 0x014340 }, - { (char*) "America/Matamoros" , 0x0143FE }, - { (char*) "America/Mazatlan" , 0x0145EB }, - { (char*) "America/Mendoza" , 0x0148DB }, - { (char*) "America/Menominee" , 0x014BAB }, - { (char*) "America/Merida" , 0x014F6B }, - { (char*) "America/Metlakatla" , 0x015216 }, - { (char*) "America/Mexico_City" , 0x015483 }, - { (char*) "America/Miquelon" , 0x0157A2 }, - { (char*) "America/Moncton" , 0x0159D4 }, - { (char*) "America/Monterrey" , 0x015FCD }, - { (char*) "America/Montevideo" , 0x0162D4 }, - { (char*) "America/Montreal" , 0x0166A9 }, - { (char*) "America/Montserrat" , 0x016D6A }, - { (char*) "America/Nassau" , 0x016DF8 }, - { (char*) "America/New_York" , 0x0171F2 }, - { (char*) "America/Nipigon" , 0x0178E2 }, - { (char*) "America/Nome" , 0x017FA3 }, - { (char*) "America/Noronha" , 0x01838B }, - { (char*) "America/North_Dakota/Beulah" , 0x01858B }, - { (char*) "America/North_Dakota/Center" , 0x0189BF }, - { (char*) "America/North_Dakota/New_Salem" , 0x018DBE }, - { (char*) "America/Nuuk" , 0x0191C3 }, - { (char*) "America/Ojinaga" , 0x0195A5 }, - { (char*) "America/Panama" , 0x01989B }, - { (char*) "America/Pangnirtung" , 0x01993C }, - { (char*) "America/Paramaribo" , 0x019C9F }, - { (char*) "America/Phoenix" , 0x019D66 }, - { (char*) "America/Port-au-Prince" , 0x019E7A }, - { (char*) "America/Port_of_Spain" , 0x01A0BB }, - { (char*) "America/Porto_Acre" , 0x01A149 }, - { (char*) "America/Porto_Velho" , 0x01A2F7 }, - { (char*) "America/Puerto_Rico" , 0x01A495 }, - { (char*) "America/Punta_Arenas" , 0x01A552 }, - { (char*) "America/Rainy_River" , 0x01AA34 }, - { (char*) "America/Rankin_Inlet" , 0x01AF4E }, - { (char*) "America/Recife" , 0x01B297 }, - { (char*) "America/Regina" , 0x01B491 }, - { (char*) "America/Resolute" , 0x01B730 }, - { (char*) "America/Rio_Branco" , 0x01BA7A }, - { (char*) "America/Rosario" , 0x01BC2C }, - { (char*) "America/Santa_Isabel" , 0x01BEFC }, - { (char*) "America/Santarem" , 0x01C33F }, - { (char*) "America/Santiago" , 0x01C4EF }, - { (char*) "America/Santo_Domingo" , 0x01CA52 }, - { (char*) "America/Sao_Paulo" , 0x01CB9B }, - { (char*) "America/Scoresbysund" , 0x01CF95 }, - { (char*) "America/Shiprock" , 0x01D396 }, - { (char*) "America/Sitka" , 0x01D7B4 }, - { (char*) "America/St_Barthelemy" , 0x01DB8F }, - { (char*) "America/St_Johns" , 0x01DC4C }, - { (char*) "America/St_Kitts" , 0x01E3C9 }, - { (char*) "America/St_Lucia" , 0x01E457 }, - { (char*) "America/St_Thomas" , 0x01E4F8 }, - { (char*) "America/St_Vincent" , 0x01E586 }, - { (char*) "America/Swift_Current" , 0x01E627 }, - { (char*) "America/Tegucigalpa" , 0x01E7B5 }, - { (char*) "America/Thule" , 0x01E883 }, - { (char*) "America/Thunder_Bay" , 0x01EA64 }, - { (char*) "America/Tijuana" , 0x01F125 }, - { (char*) "America/Toronto" , 0x01F577 }, - { (char*) "America/Tortola" , 0x01FC56 }, - { (char*) "America/Vancouver" , 0x01FCE4 }, - { (char*) "America/Virgin" , 0x02023B }, - { (char*) "America/Whitehorse" , 0x0202F8 }, - { (char*) "America/Winnipeg" , 0x02071B }, - { (char*) "America/Yakutat" , 0x020C52 }, - { (char*) "America/Yellowknife" , 0x021020 }, - { (char*) "Antarctica/Casey" , 0x0213F6 }, - { (char*) "Antarctica/Davis" , 0x021526 }, - { (char*) "Antarctica/DumontDUrville" , 0x0215FC }, - { (char*) "Antarctica/Macquarie" , 0x0216B0 }, - { (char*) "Antarctica/Mawson" , 0x021A9C }, - { (char*) "Antarctica/McMurdo" , 0x021B46 }, - { (char*) "Antarctica/Palmer" , 0x021E78 }, - { (char*) "Antarctica/Rothera" , 0x022201 }, - { (char*) "Antarctica/South_Pole" , 0x022298 }, - { (char*) "Antarctica/Syowa" , 0x0226B7 }, - { (char*) "Antarctica/Troll" , 0x02274D }, - { (char*) "Antarctica/Vostok" , 0x0227FC }, - { (char*) "Arctic/Longyearbyen" , 0x0228B8 }, - { (char*) "Asia/Aden" , 0x022B85 }, - { (char*) "Asia/Almaty" , 0x022C16 }, - { (char*) "Asia/Amman" , 0x022E9E }, - { (char*) "Asia/Anadyr" , 0x02324A }, - { (char*) "Asia/Aqtau" , 0x023550 }, - { (char*) "Asia/Aqtobe" , 0x0237CF }, - { (char*) "Asia/Ashgabat" , 0x023A4F }, - { (char*) "Asia/Ashkhabad" , 0x023BD2 }, - { (char*) "Asia/Atyrau" , 0x023D55 }, - { (char*) "Asia/Baghdad" , 0x023FDE }, - { (char*) "Asia/Bahrain" , 0x024260 }, - { (char*) "Asia/Baku" , 0x024319 }, - { (char*) "Asia/Bangkok" , 0x02460D }, - { (char*) "Asia/Barnaul" , 0x0246B1 }, - { (char*) "Asia/Beirut" , 0x0249BC }, - { (char*) "Asia/Bishkek" , 0x024CA4 }, - { (char*) "Asia/Brunei" , 0x024F1A }, - { (char*) "Asia/Calcutta" , 0x024FC0 }, - { (char*) "Asia/Chita" , 0x0250A8 }, - { (char*) "Asia/Choibalsan" , 0x0253B6 }, - { (char*) "Asia/Chongqing" , 0x025614 }, - { (char*) "Asia/Chungking" , 0x0257A9 }, - { (char*) "Asia/Colombo" , 0x02593E }, - { (char*) "Asia/Dacca" , 0x025A41 }, - { (char*) "Asia/Damascus" , 0x025B34 }, - { (char*) "Asia/Dhaka" , 0x026012 }, - { (char*) "Asia/Dili" , 0x026105 }, - { (char*) "Asia/Dubai" , 0x0261BB }, - { (char*) "Asia/Dushanbe" , 0x02624C }, - { (char*) "Asia/Famagusta" , 0x0263C6 }, - { (char*) "Asia/Gaza" , 0x02678D }, - { (char*) "Asia/Harbin" , 0x027329 }, - { (char*) "Asia/Hebron" , 0x0274BE }, - { (char*) "Asia/Ho_Chi_Minh" , 0x02806B }, - { (char*) "Asia/Hong_Kong" , 0x028163 }, - { (char*) "Asia/Hovd" , 0x028476 }, - { (char*) "Asia/Irkutsk" , 0x0286EA }, - { (char*) "Asia/Istanbul" , 0x028A08 }, - { (char*) "Asia/Jakarta" , 0x028EC4 }, - { (char*) "Asia/Jayapura" , 0x028FD5 }, - { (char*) "Asia/Jerusalem" , 0x0290C2 }, - { (char*) "Asia/Kabul" , 0x029500 }, - { (char*) "Asia/Kamchatka" , 0x0295AB }, - { (char*) "Asia/Karachi" , 0x0298A0 }, - { (char*) "Asia/Kashgar" , 0x0299B6 }, - { (char*) "Asia/Kathmandu" , 0x029A47 }, - { (char*) "Asia/Katmandu" , 0x029AF4 }, - { (char*) "Asia/Khandyga" , 0x029BA1 }, - { (char*) "Asia/Kolkata" , 0x029ED2 }, - { (char*) "Asia/Krasnoyarsk" , 0x029FBA }, - { (char*) "Asia/Kuala_Lumpur" , 0x02A2C4 }, - { (char*) "Asia/Kuching" , 0x02A3E4 }, - { (char*) "Asia/Kuwait" , 0x02A53E }, - { (char*) "Asia/Macao" , 0x02A5CF }, - { (char*) "Asia/Macau" , 0x02A8F2 }, - { (char*) "Asia/Magadan" , 0x02AC15 }, - { (char*) "Asia/Makassar" , 0x02AF20 }, - { (char*) "Asia/Manila" , 0x02B033 }, - { (char*) "Asia/Muscat" , 0x02B151 }, - { (char*) "Asia/Nicosia" , 0x02B1E2 }, - { (char*) "Asia/Novokuznetsk" , 0x02B451 }, - { (char*) "Asia/Novosibirsk" , 0x02B744 }, - { (char*) "Asia/Omsk" , 0x02BA55 }, - { (char*) "Asia/Oral" , 0x02BD53 }, - { (char*) "Asia/Phnom_Penh" , 0x02BFDF }, - { (char*) "Asia/Pontianak" , 0x02C0B3 }, - { (char*) "Asia/Pyongyang" , 0x02C1CC }, - { (char*) "Asia/Qatar" , 0x02C28F }, - { (char*) "Asia/Qostanay" , 0x02C333 }, - { (char*) "Asia/Qyzylorda" , 0x02C5C9 }, - { (char*) "Asia/Rangoon" , 0x02C862 }, - { (char*) "Asia/Riyadh" , 0x02C929 }, - { (char*) "Asia/Saigon" , 0x02C9BA }, - { (char*) "Asia/Sakhalin" , 0x02CAB2 }, - { (char*) "Asia/Samarkand" , 0x02CDC9 }, - { (char*) "Asia/Seoul" , 0x02CF54 }, - { (char*) "Asia/Shanghai" , 0x02D0FF }, - { (char*) "Asia/Singapore" , 0x02D2A0 }, - { (char*) "Asia/Srednekolymsk" , 0x02D3AC }, - { (char*) "Asia/Taipei" , 0x02D6BC }, - { (char*) "Asia/Tashkent" , 0x02D8C7 }, - { (char*) "Asia/Tbilisi" , 0x02DA52 }, - { (char*) "Asia/Tehran" , 0x02DCD3 }, - { (char*) "Asia/Tel_Aviv" , 0x02E00B }, - { (char*) "Asia/Thimbu" , 0x02E449 }, - { (char*) "Asia/Thimphu" , 0x02E4EF }, - { (char*) "Asia/Tokyo" , 0x02E595 }, - { (char*) "Asia/Tomsk" , 0x02E676 }, - { (char*) "Asia/Ujung_Pandang" , 0x02E981 }, - { (char*) "Asia/Ulaanbaatar" , 0x02EA4B }, - { (char*) "Asia/Ulan_Bator" , 0x02ECB9 }, - { (char*) "Asia/Urumqi" , 0x02EF17 }, - { (char*) "Asia/Ust-Nera" , 0x02EFB5 }, - { (char*) "Asia/Vientiane" , 0x02F2D8 }, - { (char*) "Asia/Vladivostok" , 0x02F3BE }, - { (char*) "Asia/Yakutsk" , 0x02F6C3 }, - { (char*) "Asia/Yangon" , 0x02F9C7 }, - { (char*) "Asia/Yekaterinburg" , 0x02FA8E }, - { (char*) "Asia/Yerevan" , 0x02FDA0 }, - { (char*) "Atlantic/Azores" , 0x030070 }, - { (char*) "Atlantic/Bermuda" , 0x0305FB }, - { (char*) "Atlantic/Canary" , 0x030A07 }, - { (char*) "Atlantic/Cape_Verde" , 0x030BFF }, - { (char*) "Atlantic/Faeroe" , 0x030CBA }, - { (char*) "Atlantic/Faroe" , 0x030E7F }, - { (char*) "Atlantic/Jan_Mayen" , 0x031044 }, - { (char*) "Atlantic/Madeira" , 0x031311 }, - { (char*) "Atlantic/Reykjavik" , 0x031888 }, - { (char*) "Atlantic/South_Georgia" , 0x031B85 }, - { (char*) "Atlantic/St_Helena" , 0x031C15 }, - { (char*) "Atlantic/Stanley" , 0x031CB6 }, - { (char*) "Australia/ACT" , 0x031FD7 }, - { (char*) "Australia/Adelaide" , 0x03236B }, - { (char*) "Australia/Brisbane" , 0x03271F }, - { (char*) "Australia/Broken_Hill" , 0x032863 }, - { (char*) "Australia/Canberra" , 0x032C38 }, - { (char*) "Australia/Currie" , 0x032FCC }, - { (char*) "Australia/Darwin" , 0x0333C3 }, - { (char*) "Australia/Eucla" , 0x0334CB }, - { (char*) "Australia/Hobart" , 0x03362A }, - { (char*) "Australia/LHI" , 0x033A29 }, - { (char*) "Australia/Lindeman" , 0x033CE9 }, - { (char*) "Australia/Lord_Howe" , 0x033E59 }, - { (char*) "Australia/Melbourne" , 0x034129 }, - { (char*) "Australia/North" , 0x0344C5 }, - { (char*) "Australia/NSW" , 0x0345BB }, - { (char*) "Australia/Perth" , 0x03494F }, - { (char*) "Australia/Queensland" , 0x034AAB }, - { (char*) "Australia/South" , 0x034BD8 }, - { (char*) "Australia/Sydney" , 0x034F7D }, - { (char*) "Australia/Tasmania" , 0x03532D }, - { (char*) "Australia/Victoria" , 0x035724 }, - { (char*) "Australia/West" , 0x035AB8 }, - { (char*) "Australia/Yancowinna" , 0x035BF6 }, - { (char*) "Brazil/Acre" , 0x035FAF }, - { (char*) "Brazil/DeNoronha" , 0x03615D }, - { (char*) "Brazil/East" , 0x03634D }, - { (char*) "Brazil/West" , 0x036711 }, - { (char*) "Canada/Atlantic" , 0x0368B9 }, - { (char*) "Canada/Central" , 0x036F4D }, - { (char*) "Canada/Eastern" , 0x037467 }, - { (char*) "Canada/Mountain" , 0x037B28 }, - { (char*) "Canada/Newfoundland" , 0x037EFE }, - { (char*) "Canada/Pacific" , 0x038660 }, - { (char*) "Canada/Saskatchewan" , 0x038B9E }, - { (char*) "Canada/Yukon" , 0x038E28 }, - { (char*) "CET" , 0x039239 }, - { (char*) "Chile/Continental" , 0x039694 }, - { (char*) "Chile/EasterIsland" , 0x039BEA }, - { (char*) "CST6CDT" , 0x03A08C }, - { (char*) "Cuba" , 0x03A772 }, - { (char*) "EET" , 0x03ABDB }, - { (char*) "Egypt" , 0x03AE91 }, - { (char*) "Eire" , 0x03B3BA }, - { (char*) "EST" , 0x03B99E }, - { (char*) "EST5EDT" , 0x03BA3F }, - { (char*) "Etc/GMT" , 0x03C11B }, - { (char*) "Etc/GMT+0" , 0x03C196 }, - { (char*) "Etc/GMT+1" , 0x03C211 }, - { (char*) "Etc/GMT+10" , 0x03C28E }, - { (char*) "Etc/GMT+11" , 0x03C30C }, - { (char*) "Etc/GMT+12" , 0x03C38A }, - { (char*) "Etc/GMT+2" , 0x03C408 }, - { (char*) "Etc/GMT+3" , 0x03C485 }, - { (char*) "Etc/GMT+4" , 0x03C502 }, - { (char*) "Etc/GMT+5" , 0x03C57F }, - { (char*) "Etc/GMT+6" , 0x03C5FC }, - { (char*) "Etc/GMT+7" , 0x03C679 }, - { (char*) "Etc/GMT+8" , 0x03C6F6 }, - { (char*) "Etc/GMT+9" , 0x03C773 }, - { (char*) "Etc/GMT-0" , 0x03C7F0 }, - { (char*) "Etc/GMT-1" , 0x03C86B }, - { (char*) "Etc/GMT-10" , 0x03C8E9 }, - { (char*) "Etc/GMT-11" , 0x03C968 }, - { (char*) "Etc/GMT-12" , 0x03C9E7 }, - { (char*) "Etc/GMT-13" , 0x03CA66 }, - { (char*) "Etc/GMT-14" , 0x03CAE5 }, - { (char*) "Etc/GMT-2" , 0x03CB64 }, - { (char*) "Etc/GMT-3" , 0x03CBE2 }, - { (char*) "Etc/GMT-4" , 0x03CC60 }, - { (char*) "Etc/GMT-5" , 0x03CCDE }, - { (char*) "Etc/GMT-6" , 0x03CD5C }, - { (char*) "Etc/GMT-7" , 0x03CDDA }, - { (char*) "Etc/GMT-8" , 0x03CE58 }, - { (char*) "Etc/GMT-9" , 0x03CED6 }, - { (char*) "Etc/GMT0" , 0x03CF54 }, - { (char*) "Etc/Greenwich" , 0x03CFCF }, - { (char*) "Etc/UCT" , 0x03D04A }, - { (char*) "Etc/Universal" , 0x03D0C5 }, - { (char*) "Etc/UTC" , 0x03D140 }, - { (char*) "Etc/Zulu" , 0x03D1BB }, - { (char*) "Europe/Amsterdam" , 0x03D236 }, - { (char*) "Europe/Andorra" , 0x03D671 }, - { (char*) "Europe/Astrakhan" , 0x03D802 }, - { (char*) "Europe/Athens" , 0x03DAF6 }, - { (char*) "Europe/Belfast" , 0x03DDAC }, - { (char*) "Europe/Belgrade" , 0x03E3F7 }, - { (char*) "Europe/Berlin" , 0x03E5E1 }, - { (char*) "Europe/Bratislava" , 0x03E8BD }, - { (char*) "Europe/Brussels" , 0x03EB9C }, - { (char*) "Europe/Bucharest" , 0x03EFF7 }, - { (char*) "Europe/Budapest" , 0x03F298 }, - { (char*) "Europe/Busingen" , 0x03F5A2 }, - { (char*) "Europe/Chisinau" , 0x03F7A7 }, - { (char*) "Europe/Copenhagen" , 0x03FAA6 }, - { (char*) "Europe/Dublin" , 0x03FD21 }, - { (char*) "Europe/Gibraltar" , 0x040305 }, - { (char*) "Europe/Guernsey" , 0x0407D5 }, - { (char*) "Europe/Helsinki" , 0x040E2C }, - { (char*) "Europe/Isle_of_Man" , 0x041019 }, - { (char*) "Europe/Istanbul" , 0x041664 }, - { (char*) "Europe/Jersey" , 0x041B20 }, - { (char*) "Europe/Kaliningrad" , 0x042177 }, - { (char*) "Europe/Kiev" , 0x04251F }, - { (char*) "Europe/Kirov" , 0x042759 }, - { (char*) "Europe/Kyiv" , 0x042A52 }, - { (char*) "Europe/Lisbon" , 0x042C9B }, - { (char*) "Europe/Ljubljana" , 0x043271 }, - { (char*) "Europe/London" , 0x04345B }, - { (char*) "Europe/Luxembourg" , 0x043AA6 }, - { (char*) "Europe/Madrid" , 0x043EF1 }, - { (char*) "Europe/Malta" , 0x04428E }, - { (char*) "Europe/Mariehamn" , 0x04463A }, - { (char*) "Europe/Minsk" , 0x044827 }, - { (char*) "Europe/Monaco" , 0x044B5B }, - { (char*) "Europe/Moscow" , 0x044FC1 }, - { (char*) "Europe/Nicosia" , 0x04536D }, - { (char*) "Europe/Oslo" , 0x0455CE }, - { (char*) "Europe/Paris" , 0x04587E }, - { (char*) "Europe/Podgorica" , 0x045CDB }, - { (char*) "Europe/Prague" , 0x045EC5 }, - { (char*) "Europe/Riga" , 0x0461A4 }, - { (char*) "Europe/Rome" , 0x046466 }, - { (char*) "Europe/Samara" , 0x046825 }, - { (char*) "Europe/San_Marino" , 0x046B26 }, - { (char*) "Europe/Sarajevo" , 0x046EE5 }, - { (char*) "Europe/Saratov" , 0x0470CF }, - { (char*) "Europe/Simferopol" , 0x0473C1 }, - { (char*) "Europe/Skopje" , 0x047734 }, - { (char*) "Europe/Sofia" , 0x04791E }, - { (char*) "Europe/Stockholm" , 0x047B7A }, - { (char*) "Europe/Tallinn" , 0x047D77 }, - { (char*) "Europe/Tirane" , 0x048026 }, - { (char*) "Europe/Tiraspol" , 0x04828E }, - { (char*) "Europe/Ulyanovsk" , 0x04858D }, - { (char*) "Europe/Uzhgorod" , 0x0488A3 }, - { (char*) "Europe/Vaduz" , 0x048ADD }, - { (char*) "Europe/Vatican" , 0x048CC7 }, - { (char*) "Europe/Vienna" , 0x049086 }, - { (char*) "Europe/Vilnius" , 0x049324 }, - { (char*) "Europe/Volgograd" , 0x0495D4 }, - { (char*) "Europe/Warsaw" , 0x0498E3 }, - { (char*) "Europe/Zagreb" , 0x049C8A }, - { (char*) "Europe/Zaporozhye" , 0x049E74 }, - { (char*) "Europe/Zurich" , 0x04A0AE }, - { (char*) "Factory" , 0x04A2AB }, - { (char*) "GB" , 0x04A328 }, - { (char*) "GB-Eire" , 0x04A973 }, - { (char*) "GMT" , 0x04AFBE }, - { (char*) "GMT+0" , 0x04B039 }, - { (char*) "GMT-0" , 0x04B0B4 }, - { (char*) "GMT0" , 0x04B12F }, - { (char*) "Greenwich" , 0x04B1AA }, - { (char*) "Hongkong" , 0x04B225 }, - { (char*) "HST" , 0x04B538 }, - { (char*) "Iceland" , 0x04B621 }, - { (char*) "Indian/Antananarivo" , 0x04B6AF }, - { (char*) "Indian/Chagos" , 0x04B75B }, - { (char*) "Indian/Christmas" , 0x04B7FF }, - { (char*) "Indian/Cocos" , 0x04B890 }, - { (char*) "Indian/Comoro" , 0x04B928 }, - { (char*) "Indian/Kerguelen" , 0x04B9B7 }, - { (char*) "Indian/Mahe" , 0x04BA48 }, - { (char*) "Indian/Maldives" , 0x04BAD9 }, - { (char*) "Indian/Mauritius" , 0x04BB7D }, - { (char*) "Indian/Mayotte" , 0x04BC3C }, - { (char*) "Indian/Reunion" , 0x04BCCB }, - { (char*) "Iran" , 0x04BD5C }, - { (char*) "Israel" , 0x04C094 }, - { (char*) "Jamaica" , 0x04C4D2 }, - { (char*) "Japan" , 0x04C631 }, - { (char*) "Kwajalein" , 0x04C712 }, - { (char*) "Libya" , 0x04C7F9 }, - { (char*) "MET" , 0x04C9B4 }, - { (char*) "Mexico/BajaNorte" , 0x04CE0F }, - { (char*) "Mexico/BajaSur" , 0x04D252 }, - { (char*) "Mexico/General" , 0x04D510 }, - { (char*) "MST" , 0x04D821 }, - { (char*) "MST7MDT" , 0x04D91D }, - { (char*) "Navajo" , 0x04DD3B }, - { (char*) "NZ" , 0x04E159 }, - { (char*) "NZ-CHAT" , 0x04E578 }, - { (char*) "Pacific/Apia" , 0x04E8AC }, - { (char*) "Pacific/Auckland" , 0x04EA4F }, - { (char*) "Pacific/Bougainville" , 0x04EE81 }, - { (char*) "Pacific/Chatham" , 0x04EF62 }, - { (char*) "Pacific/Chuuk" , 0x04F2A5 }, - { (char*) "Pacific/Easter" , 0x04F383 }, - { (char*) "Pacific/Efate" , 0x04F832 }, - { (char*) "Pacific/Enderbury" , 0x04F994 }, - { (char*) "Pacific/Fakaofo" , 0x04FA4C }, - { (char*) "Pacific/Fiji" , 0x04FAF1 }, - { (char*) "Pacific/Funafuti" , 0x04FC89 }, - { (char*) "Pacific/Galapagos" , 0x04FD1B }, - { (char*) "Pacific/Gambier" , 0x04FDE7 }, - { (char*) "Pacific/Guadalcanal" , 0x04FE86 }, - { (char*) "Pacific/Guam" , 0x04FF18 }, - { (char*) "Pacific/Honolulu" , 0x050082 }, - { (char*) "Pacific/Johnston" , 0x050171 }, - { (char*) "Pacific/Kanton" , 0x05025A }, - { (char*) "Pacific/Kiritimati" , 0x050321 }, - { (char*) "Pacific/Kosrae" , 0x0503E7 }, - { (char*) "Pacific/Kwajalein" , 0x0504EB }, - { (char*) "Pacific/Majuro" , 0x0505DB }, - { (char*) "Pacific/Marquesas" , 0x0506D9 }, - { (char*) "Pacific/Midway" , 0x050781 }, - { (char*) "Pacific/Nauru" , 0x050844 }, - { (char*) "Pacific/Niue" , 0x050907 }, - { (char*) "Pacific/Norfolk" , 0x0509AD }, - { (char*) "Pacific/Noumea" , 0x050AA6 }, - { (char*) "Pacific/Pago_Pago" , 0x050B78 }, - { (char*) "Pacific/Palau" , 0x050C16 }, - { (char*) "Pacific/Pitcairn" , 0x050CB6 }, - { (char*) "Pacific/Pohnpei" , 0x050D5B }, - { (char*) "Pacific/Ponape" , 0x050E4B }, - { (char*) "Pacific/Port_Moresby" , 0x050EDD }, - { (char*) "Pacific/Rarotonga" , 0x050F9B }, - { (char*) "Pacific/Saipan" , 0x05113D }, - { (char*) "Pacific/Samoa" , 0x05129E }, - { (char*) "Pacific/Tahiti" , 0x05133C }, - { (char*) "Pacific/Tarawa" , 0x0513DC }, - { (char*) "Pacific/Tongatapu" , 0x05147D }, - { (char*) "Pacific/Truk" , 0x051576 }, - { (char*) "Pacific/Wake" , 0x05161C }, - { (char*) "Pacific/Wallis" , 0x0516B9 }, - { (char*) "Pacific/Yap" , 0x05174B }, - { (char*) "Poland" , 0x0517F1 }, - { (char*) "Portugal" , 0x051B98 }, - { (char*) "PRC" , 0x05215B }, - { (char*) "PST8PDT" , 0x0522F0 }, - { (char*) "ROC" , 0x05280A }, - { (char*) "ROK" , 0x052A15 }, - { (char*) "Singapore" , 0x052BC0 }, - { (char*) "Turkey" , 0x052CCC }, - { (char*) "UCT" , 0x053188 }, - { (char*) "Universal" , 0x053203 }, - { (char*) "US/Alaska" , 0x05327E }, - { (char*) "US/Aleutian" , 0x05365B }, - { (char*) "US/Arizona" , 0x053A30 }, - { (char*) "US/Central" , 0x053B2C }, - { (char*) "US/East-Indiana" , 0x054212 }, - { (char*) "US/Eastern" , 0x054431 }, - { (char*) "US/Hawaii" , 0x054B0D }, - { (char*) "US/Indiana-Starke" , 0x054BF6 }, - { (char*) "US/Michigan" , 0x054FFA }, - { (char*) "US/Mountain" , 0x055389 }, - { (char*) "US/Pacific" , 0x0557A7 }, - { (char*) "US/Samoa" , 0x055CC1 }, - { (char*) "UTC" , 0x055D5F }, - { (char*) "W-SU" , 0x055DDA }, - { (char*) "WET" , 0x056172 }, - { (char*) "Zulu" , 0x056735 }, + { (char*) "America/Coyhaique" , 0x00B238 }, + { (char*) "America/Creston" , 0x00B7A2 }, + { (char*) "America/Cuiaba" , 0x00B85E }, + { (char*) "America/Curacao" , 0x00BC1B }, + { (char*) "America/Danmarkshavn" , 0x00BCBE }, + { (char*) "America/Dawson" , 0x00BEA3 }, + { (char*) "America/Dawson_Creek" , 0x00C2C6 }, + { (char*) "America/Denver" , 0x00C59D }, + { (char*) "America/Detroit" , 0x00C9D0 }, + { (char*) "America/Dominica" , 0x00CD78 }, + { (char*) "America/Edmonton" , 0x00CE06 }, + { (char*) "America/Eirunepe" , 0x00D1FE }, + { (char*) "America/El_Salvador" , 0x00D3CD }, + { (char*) "America/Ensenada" , 0x00D489 }, + { (char*) "America/Fort_Nelson" , 0x00D8CC }, + { (char*) "America/Fort_Wayne" , 0x00DE94 }, + { (char*) "America/Fortaleza" , 0x00E0B3 }, + { (char*) "America/Glace_Bay" , 0x00E2C9 }, + { (char*) "America/Godthab" , 0x00E660 }, + { (char*) "America/Goose_Bay" , 0x00EA31 }, + { (char*) "America/Grand_Turk" , 0x00F089 }, + { (char*) "America/Grenada" , 0x00F3EA }, + { (char*) "America/Guadeloupe" , 0x00F478 }, + { (char*) "America/Guatemala" , 0x00F506 }, + { (char*) "America/Guayaquil" , 0x00F5E6 }, + { (char*) "America/Guyana" , 0x00F6B7 }, + { (char*) "America/Halifax" , 0x00F778 }, + { (char*) "America/Havana" , 0x00FE2A }, + { (char*) "America/Hermosillo" , 0x010293 }, + { (char*) "America/Indiana/Indianapolis" , 0x0103A7 }, + { (char*) "America/Indiana/Knox" , 0x0105DF }, + { (char*) "America/Indiana/Marengo" , 0x0109F8 }, + { (char*) "America/Indiana/Petersburg" , 0x010C52 }, + { (char*) "America/Indiana/Tell_City" , 0x010F1C }, + { (char*) "America/Indiana/Vevay" , 0x011146 }, + { (char*) "America/Indiana/Vincennes" , 0x0112DD }, + { (char*) "America/Indiana/Winamac" , 0x011533 }, + { (char*) "America/Indianapolis" , 0x0117B0 }, + { (char*) "America/Inuvik" , 0x0119CF }, + { (char*) "America/Iqaluit" , 0x011D20 }, + { (char*) "America/Jamaica" , 0x01209C }, + { (char*) "America/Jujuy" , 0x0121FB }, + { (char*) "America/Juneau" , 0x0124B9 }, + { (char*) "America/Kentucky/Louisville" , 0x01289F }, + { (char*) "America/Kentucky/Monticello" , 0x012DA3 }, + { (char*) "America/Knox_IN" , 0x01318F }, + { (char*) "America/Kralendijk" , 0x013593 }, + { (char*) "America/La_Paz" , 0x013650 }, + { (char*) "America/Lima" , 0x013706 }, + { (char*) "America/Los_Angeles" , 0x01382D }, + { (char*) "America/Louisville" , 0x013D4E }, + { (char*) "America/Lower_Princes" , 0x014234 }, + { (char*) "America/Maceio" , 0x0142F1 }, + { (char*) "America/Managua" , 0x014503 }, + { (char*) "America/Manaus" , 0x014636 }, + { (char*) "America/Marigot" , 0x0147ED }, + { (char*) "America/Martinique" , 0x0148AA }, + { (char*) "America/Matamoros" , 0x014968 }, + { (char*) "America/Mazatlan" , 0x014B55 }, + { (char*) "America/Mendoza" , 0x014E45 }, + { (char*) "America/Menominee" , 0x015115 }, + { (char*) "America/Merida" , 0x0154D5 }, + { (char*) "America/Metlakatla" , 0x015780 }, + { (char*) "America/Mexico_City" , 0x0159ED }, + { (char*) "America/Miquelon" , 0x015D0C }, + { (char*) "America/Moncton" , 0x015F3E }, + { (char*) "America/Monterrey" , 0x016537 }, + { (char*) "America/Montevideo" , 0x01683E }, + { (char*) "America/Montreal" , 0x016C13 }, + { (char*) "America/Montserrat" , 0x0172D4 }, + { (char*) "America/Nassau" , 0x017362 }, + { (char*) "America/New_York" , 0x01775C }, + { (char*) "America/Nipigon" , 0x017E4C }, + { (char*) "America/Nome" , 0x01850D }, + { (char*) "America/Noronha" , 0x0188F5 }, + { (char*) "America/North_Dakota/Beulah" , 0x018AF5 }, + { (char*) "America/North_Dakota/Center" , 0x018F29 }, + { (char*) "America/North_Dakota/New_Salem" , 0x019328 }, + { (char*) "America/Nuuk" , 0x01972D }, + { (char*) "America/Ojinaga" , 0x019B0F }, + { (char*) "America/Panama" , 0x019E05 }, + { (char*) "America/Pangnirtung" , 0x019EA6 }, + { (char*) "America/Paramaribo" , 0x01A209 }, + { (char*) "America/Phoenix" , 0x01A2D0 }, + { (char*) "America/Port-au-Prince" , 0x01A3E4 }, + { (char*) "America/Port_of_Spain" , 0x01A625 }, + { (char*) "America/Porto_Acre" , 0x01A6B3 }, + { (char*) "America/Porto_Velho" , 0x01A861 }, + { (char*) "America/Puerto_Rico" , 0x01A9FF }, + { (char*) "America/Punta_Arenas" , 0x01AABC }, + { (char*) "America/Rainy_River" , 0x01AF9B }, + { (char*) "America/Rankin_Inlet" , 0x01B4B5 }, + { (char*) "America/Recife" , 0x01B7FE }, + { (char*) "America/Regina" , 0x01B9F8 }, + { (char*) "America/Resolute" , 0x01BC97 }, + { (char*) "America/Rio_Branco" , 0x01BFE1 }, + { (char*) "America/Rosario" , 0x01C193 }, + { (char*) "America/Santa_Isabel" , 0x01C463 }, + { (char*) "America/Santarem" , 0x01C8A6 }, + { (char*) "America/Santiago" , 0x01CA56 }, + { (char*) "America/Santo_Domingo" , 0x01CFB9 }, + { (char*) "America/Sao_Paulo" , 0x01D102 }, + { (char*) "America/Scoresbysund" , 0x01D4FC }, + { (char*) "America/Shiprock" , 0x01D8FD }, + { (char*) "America/Sitka" , 0x01DD1B }, + { (char*) "America/St_Barthelemy" , 0x01E0F6 }, + { (char*) "America/St_Johns" , 0x01E1B3 }, + { (char*) "America/St_Kitts" , 0x01E930 }, + { (char*) "America/St_Lucia" , 0x01E9BE }, + { (char*) "America/St_Thomas" , 0x01EA5F }, + { (char*) "America/St_Vincent" , 0x01EAED }, + { (char*) "America/Swift_Current" , 0x01EB8E }, + { (char*) "America/Tegucigalpa" , 0x01ED1C }, + { (char*) "America/Thule" , 0x01EDEA }, + { (char*) "America/Thunder_Bay" , 0x01EFCB }, + { (char*) "America/Tijuana" , 0x01F68C }, + { (char*) "America/Toronto" , 0x01FADE }, + { (char*) "America/Tortola" , 0x0201BD }, + { (char*) "America/Vancouver" , 0x02024B }, + { (char*) "America/Virgin" , 0x0207A2 }, + { (char*) "America/Whitehorse" , 0x02085F }, + { (char*) "America/Winnipeg" , 0x020C82 }, + { (char*) "America/Yakutat" , 0x0211B9 }, + { (char*) "America/Yellowknife" , 0x021587 }, + { (char*) "Antarctica/Casey" , 0x02195D }, + { (char*) "Antarctica/Davis" , 0x021A8D }, + { (char*) "Antarctica/DumontDUrville" , 0x021B63 }, + { (char*) "Antarctica/Macquarie" , 0x021C17 }, + { (char*) "Antarctica/Mawson" , 0x022003 }, + { (char*) "Antarctica/McMurdo" , 0x0220AD }, + { (char*) "Antarctica/Palmer" , 0x0223DF }, + { (char*) "Antarctica/Rothera" , 0x022768 }, + { (char*) "Antarctica/South_Pole" , 0x0227FF }, + { (char*) "Antarctica/Syowa" , 0x022C1E }, + { (char*) "Antarctica/Troll" , 0x022CB4 }, + { (char*) "Antarctica/Vostok" , 0x022D63 }, + { (char*) "Arctic/Longyearbyen" , 0x022E1F }, + { (char*) "Asia/Aden" , 0x0230EC }, + { (char*) "Asia/Almaty" , 0x02317D }, + { (char*) "Asia/Amman" , 0x023405 }, + { (char*) "Asia/Anadyr" , 0x0237B1 }, + { (char*) "Asia/Aqtau" , 0x023AB7 }, + { (char*) "Asia/Aqtobe" , 0x023D36 }, + { (char*) "Asia/Ashgabat" , 0x023FB6 }, + { (char*) "Asia/Ashkhabad" , 0x024139 }, + { (char*) "Asia/Atyrau" , 0x0242BC }, + { (char*) "Asia/Baghdad" , 0x024545 }, + { (char*) "Asia/Bahrain" , 0x0247C7 }, + { (char*) "Asia/Baku" , 0x024880 }, + { (char*) "Asia/Bangkok" , 0x024B74 }, + { (char*) "Asia/Barnaul" , 0x024C18 }, + { (char*) "Asia/Beirut" , 0x024F23 }, + { (char*) "Asia/Bishkek" , 0x02520B }, + { (char*) "Asia/Brunei" , 0x025481 }, + { (char*) "Asia/Calcutta" , 0x025527 }, + { (char*) "Asia/Chita" , 0x02560F }, + { (char*) "Asia/Choibalsan" , 0x02591D }, + { (char*) "Asia/Chongqing" , 0x025B7B }, + { (char*) "Asia/Chungking" , 0x025D10 }, + { (char*) "Asia/Colombo" , 0x025EA5 }, + { (char*) "Asia/Dacca" , 0x025FA8 }, + { (char*) "Asia/Damascus" , 0x02609B }, + { (char*) "Asia/Dhaka" , 0x026579 }, + { (char*) "Asia/Dili" , 0x02666C }, + { (char*) "Asia/Dubai" , 0x026722 }, + { (char*) "Asia/Dushanbe" , 0x0267B3 }, + { (char*) "Asia/Famagusta" , 0x02692D }, + { (char*) "Asia/Gaza" , 0x026CF4 }, + { (char*) "Asia/Harbin" , 0x027890 }, + { (char*) "Asia/Hebron" , 0x027A25 }, + { (char*) "Asia/Ho_Chi_Minh" , 0x0285D2 }, + { (char*) "Asia/Hong_Kong" , 0x0286CA }, + { (char*) "Asia/Hovd" , 0x0289DD }, + { (char*) "Asia/Irkutsk" , 0x028C51 }, + { (char*) "Asia/Istanbul" , 0x028F6F }, + { (char*) "Asia/Jakarta" , 0x02942B }, + { (char*) "Asia/Jayapura" , 0x02953C }, + { (char*) "Asia/Jerusalem" , 0x029629 }, + { (char*) "Asia/Kabul" , 0x029A67 }, + { (char*) "Asia/Kamchatka" , 0x029B12 }, + { (char*) "Asia/Karachi" , 0x029E07 }, + { (char*) "Asia/Kashgar" , 0x029F1D }, + { (char*) "Asia/Kathmandu" , 0x029FAE }, + { (char*) "Asia/Katmandu" , 0x02A05B }, + { (char*) "Asia/Khandyga" , 0x02A108 }, + { (char*) "Asia/Kolkata" , 0x02A439 }, + { (char*) "Asia/Krasnoyarsk" , 0x02A521 }, + { (char*) "Asia/Kuala_Lumpur" , 0x02A82B }, + { (char*) "Asia/Kuching" , 0x02A94B }, + { (char*) "Asia/Kuwait" , 0x02AAA5 }, + { (char*) "Asia/Macao" , 0x02AB36 }, + { (char*) "Asia/Macau" , 0x02AE59 }, + { (char*) "Asia/Magadan" , 0x02B17C }, + { (char*) "Asia/Makassar" , 0x02B487 }, + { (char*) "Asia/Manila" , 0x02B59A }, + { (char*) "Asia/Muscat" , 0x02B6B8 }, + { (char*) "Asia/Nicosia" , 0x02B749 }, + { (char*) "Asia/Novokuznetsk" , 0x02B9B8 }, + { (char*) "Asia/Novosibirsk" , 0x02BCAB }, + { (char*) "Asia/Omsk" , 0x02BFBC }, + { (char*) "Asia/Oral" , 0x02C2BA }, + { (char*) "Asia/Phnom_Penh" , 0x02C546 }, + { (char*) "Asia/Pontianak" , 0x02C61A }, + { (char*) "Asia/Pyongyang" , 0x02C733 }, + { (char*) "Asia/Qatar" , 0x02C7F6 }, + { (char*) "Asia/Qostanay" , 0x02C89A }, + { (char*) "Asia/Qyzylorda" , 0x02CB30 }, + { (char*) "Asia/Rangoon" , 0x02CDC9 }, + { (char*) "Asia/Riyadh" , 0x02CE90 }, + { (char*) "Asia/Saigon" , 0x02CF21 }, + { (char*) "Asia/Sakhalin" , 0x02D019 }, + { (char*) "Asia/Samarkand" , 0x02D330 }, + { (char*) "Asia/Seoul" , 0x02D4BB }, + { (char*) "Asia/Shanghai" , 0x02D666 }, + { (char*) "Asia/Singapore" , 0x02D807 }, + { (char*) "Asia/Srednekolymsk" , 0x02D913 }, + { (char*) "Asia/Taipei" , 0x02DC23 }, + { (char*) "Asia/Tashkent" , 0x02DE2E }, + { (char*) "Asia/Tbilisi" , 0x02DFB9 }, + { (char*) "Asia/Tehran" , 0x02E23A }, + { (char*) "Asia/Tel_Aviv" , 0x02E572 }, + { (char*) "Asia/Thimbu" , 0x02E9B0 }, + { (char*) "Asia/Thimphu" , 0x02EA56 }, + { (char*) "Asia/Tokyo" , 0x02EAFC }, + { (char*) "Asia/Tomsk" , 0x02EBDD }, + { (char*) "Asia/Ujung_Pandang" , 0x02EEE8 }, + { (char*) "Asia/Ulaanbaatar" , 0x02EFB2 }, + { (char*) "Asia/Ulan_Bator" , 0x02F220 }, + { (char*) "Asia/Urumqi" , 0x02F47E }, + { (char*) "Asia/Ust-Nera" , 0x02F51C }, + { (char*) "Asia/Vientiane" , 0x02F83F }, + { (char*) "Asia/Vladivostok" , 0x02F925 }, + { (char*) "Asia/Yakutsk" , 0x02FC2A }, + { (char*) "Asia/Yangon" , 0x02FF2E }, + { (char*) "Asia/Yekaterinburg" , 0x02FFF5 }, + { (char*) "Asia/Yerevan" , 0x030307 }, + { (char*) "Atlantic/Azores" , 0x0305D7 }, + { (char*) "Atlantic/Bermuda" , 0x030B62 }, + { (char*) "Atlantic/Canary" , 0x030F6E }, + { (char*) "Atlantic/Cape_Verde" , 0x031166 }, + { (char*) "Atlantic/Faeroe" , 0x031221 }, + { (char*) "Atlantic/Faroe" , 0x0313E6 }, + { (char*) "Atlantic/Jan_Mayen" , 0x0315AB }, + { (char*) "Atlantic/Madeira" , 0x031878 }, + { (char*) "Atlantic/Reykjavik" , 0x031DEF }, + { (char*) "Atlantic/South_Georgia" , 0x0320EC }, + { (char*) "Atlantic/St_Helena" , 0x03217C }, + { (char*) "Atlantic/Stanley" , 0x03221D }, + { (char*) "Australia/ACT" , 0x03253E }, + { (char*) "Australia/Adelaide" , 0x0328D2 }, + { (char*) "Australia/Brisbane" , 0x032C86 }, + { (char*) "Australia/Broken_Hill" , 0x032DCA }, + { (char*) "Australia/Canberra" , 0x03319F }, + { (char*) "Australia/Currie" , 0x033533 }, + { (char*) "Australia/Darwin" , 0x03392A }, + { (char*) "Australia/Eucla" , 0x033A32 }, + { (char*) "Australia/Hobart" , 0x033B91 }, + { (char*) "Australia/LHI" , 0x033F90 }, + { (char*) "Australia/Lindeman" , 0x034250 }, + { (char*) "Australia/Lord_Howe" , 0x0343C0 }, + { (char*) "Australia/Melbourne" , 0x034690 }, + { (char*) "Australia/North" , 0x034A2C }, + { (char*) "Australia/NSW" , 0x034B22 }, + { (char*) "Australia/Perth" , 0x034EB6 }, + { (char*) "Australia/Queensland" , 0x035012 }, + { (char*) "Australia/South" , 0x03513F }, + { (char*) "Australia/Sydney" , 0x0354E4 }, + { (char*) "Australia/Tasmania" , 0x035894 }, + { (char*) "Australia/Victoria" , 0x035C8B }, + { (char*) "Australia/West" , 0x03601F }, + { (char*) "Australia/Yancowinna" , 0x03615D }, + { (char*) "Brazil/Acre" , 0x036516 }, + { (char*) "Brazil/DeNoronha" , 0x0366C4 }, + { (char*) "Brazil/East" , 0x0368B4 }, + { (char*) "Brazil/West" , 0x036C78 }, + { (char*) "Canada/Atlantic" , 0x036E20 }, + { (char*) "Canada/Central" , 0x0374B4 }, + { (char*) "Canada/Eastern" , 0x0379CE }, + { (char*) "Canada/Mountain" , 0x03808F }, + { (char*) "Canada/Newfoundland" , 0x038465 }, + { (char*) "Canada/Pacific" , 0x038BC7 }, + { (char*) "Canada/Saskatchewan" , 0x039105 }, + { (char*) "Canada/Yukon" , 0x03938F }, + { (char*) "CET" , 0x0397A0 }, + { (char*) "Chile/Continental" , 0x039BFB }, + { (char*) "Chile/EasterIsland" , 0x03A151 }, + { (char*) "CST6CDT" , 0x03A5F3 }, + { (char*) "Cuba" , 0x03ACD9 }, + { (char*) "EET" , 0x03B142 }, + { (char*) "Egypt" , 0x03B3F8 }, + { (char*) "Eire" , 0x03B921 }, + { (char*) "EST" , 0x03BF05 }, + { (char*) "EST5EDT" , 0x03BFA6 }, + { (char*) "Etc/GMT" , 0x03C682 }, + { (char*) "Etc/GMT+0" , 0x03C6FD }, + { (char*) "Etc/GMT+1" , 0x03C778 }, + { (char*) "Etc/GMT+10" , 0x03C7F5 }, + { (char*) "Etc/GMT+11" , 0x03C873 }, + { (char*) "Etc/GMT+12" , 0x03C8F1 }, + { (char*) "Etc/GMT+2" , 0x03C96F }, + { (char*) "Etc/GMT+3" , 0x03C9EC }, + { (char*) "Etc/GMT+4" , 0x03CA69 }, + { (char*) "Etc/GMT+5" , 0x03CAE6 }, + { (char*) "Etc/GMT+6" , 0x03CB63 }, + { (char*) "Etc/GMT+7" , 0x03CBE0 }, + { (char*) "Etc/GMT+8" , 0x03CC5D }, + { (char*) "Etc/GMT+9" , 0x03CCDA }, + { (char*) "Etc/GMT-0" , 0x03CD57 }, + { (char*) "Etc/GMT-1" , 0x03CDD2 }, + { (char*) "Etc/GMT-10" , 0x03CE50 }, + { (char*) "Etc/GMT-11" , 0x03CECF }, + { (char*) "Etc/GMT-12" , 0x03CF4E }, + { (char*) "Etc/GMT-13" , 0x03CFCD }, + { (char*) "Etc/GMT-14" , 0x03D04C }, + { (char*) "Etc/GMT-2" , 0x03D0CB }, + { (char*) "Etc/GMT-3" , 0x03D149 }, + { (char*) "Etc/GMT-4" , 0x03D1C7 }, + { (char*) "Etc/GMT-5" , 0x03D245 }, + { (char*) "Etc/GMT-6" , 0x03D2C3 }, + { (char*) "Etc/GMT-7" , 0x03D341 }, + { (char*) "Etc/GMT-8" , 0x03D3BF }, + { (char*) "Etc/GMT-9" , 0x03D43D }, + { (char*) "Etc/GMT0" , 0x03D4BB }, + { (char*) "Etc/Greenwich" , 0x03D536 }, + { (char*) "Etc/UCT" , 0x03D5B1 }, + { (char*) "Etc/Universal" , 0x03D62C }, + { (char*) "Etc/UTC" , 0x03D6A7 }, + { (char*) "Etc/Zulu" , 0x03D722 }, + { (char*) "Europe/Amsterdam" , 0x03D79D }, + { (char*) "Europe/Andorra" , 0x03DBD8 }, + { (char*) "Europe/Astrakhan" , 0x03DD69 }, + { (char*) "Europe/Athens" , 0x03E05D }, + { (char*) "Europe/Belfast" , 0x03E313 }, + { (char*) "Europe/Belgrade" , 0x03E95E }, + { (char*) "Europe/Berlin" , 0x03EB48 }, + { (char*) "Europe/Bratislava" , 0x03EE24 }, + { (char*) "Europe/Brussels" , 0x03F103 }, + { (char*) "Europe/Bucharest" , 0x03F55E }, + { (char*) "Europe/Budapest" , 0x03F7FF }, + { (char*) "Europe/Busingen" , 0x03FB09 }, + { (char*) "Europe/Chisinau" , 0x03FD0E }, + { (char*) "Europe/Copenhagen" , 0x04000D }, + { (char*) "Europe/Dublin" , 0x040288 }, + { (char*) "Europe/Gibraltar" , 0x04086C }, + { (char*) "Europe/Guernsey" , 0x040D3C }, + { (char*) "Europe/Helsinki" , 0x041393 }, + { (char*) "Europe/Isle_of_Man" , 0x041580 }, + { (char*) "Europe/Istanbul" , 0x041BCB }, + { (char*) "Europe/Jersey" , 0x042087 }, + { (char*) "Europe/Kaliningrad" , 0x0426DE }, + { (char*) "Europe/Kiev" , 0x042A86 }, + { (char*) "Europe/Kirov" , 0x042CC0 }, + { (char*) "Europe/Kyiv" , 0x042FB9 }, + { (char*) "Europe/Lisbon" , 0x043202 }, + { (char*) "Europe/Ljubljana" , 0x0437D8 }, + { (char*) "Europe/London" , 0x0439C2 }, + { (char*) "Europe/Luxembourg" , 0x04400D }, + { (char*) "Europe/Madrid" , 0x044458 }, + { (char*) "Europe/Malta" , 0x0447F5 }, + { (char*) "Europe/Mariehamn" , 0x044BA1 }, + { (char*) "Europe/Minsk" , 0x044D8E }, + { (char*) "Europe/Monaco" , 0x0450C2 }, + { (char*) "Europe/Moscow" , 0x045528 }, + { (char*) "Europe/Nicosia" , 0x0458D4 }, + { (char*) "Europe/Oslo" , 0x045B35 }, + { (char*) "Europe/Paris" , 0x045DE5 }, + { (char*) "Europe/Podgorica" , 0x046242 }, + { (char*) "Europe/Prague" , 0x04642C }, + { (char*) "Europe/Riga" , 0x04670B }, + { (char*) "Europe/Rome" , 0x0469CD }, + { (char*) "Europe/Samara" , 0x046D8C }, + { (char*) "Europe/San_Marino" , 0x04708D }, + { (char*) "Europe/Sarajevo" , 0x04744C }, + { (char*) "Europe/Saratov" , 0x047636 }, + { (char*) "Europe/Simferopol" , 0x047928 }, + { (char*) "Europe/Skopje" , 0x047C9B }, + { (char*) "Europe/Sofia" , 0x047E85 }, + { (char*) "Europe/Stockholm" , 0x0480E1 }, + { (char*) "Europe/Tallinn" , 0x0482DE }, + { (char*) "Europe/Tirane" , 0x04858D }, + { (char*) "Europe/Tiraspol" , 0x0487F5 }, + { (char*) "Europe/Ulyanovsk" , 0x048AF4 }, + { (char*) "Europe/Uzhgorod" , 0x048E0A }, + { (char*) "Europe/Vaduz" , 0x049044 }, + { (char*) "Europe/Vatican" , 0x04922E }, + { (char*) "Europe/Vienna" , 0x0495ED }, + { (char*) "Europe/Vilnius" , 0x04988B }, + { (char*) "Europe/Volgograd" , 0x049B3B }, + { (char*) "Europe/Warsaw" , 0x049E4A }, + { (char*) "Europe/Zagreb" , 0x04A1F1 }, + { (char*) "Europe/Zaporozhye" , 0x04A3DB }, + { (char*) "Europe/Zurich" , 0x04A615 }, + { (char*) "Factory" , 0x04A812 }, + { (char*) "GB" , 0x04A88F }, + { (char*) "GB-Eire" , 0x04AEDA }, + { (char*) "GMT" , 0x04B525 }, + { (char*) "GMT+0" , 0x04B5A0 }, + { (char*) "GMT-0" , 0x04B61B }, + { (char*) "GMT0" , 0x04B696 }, + { (char*) "Greenwich" , 0x04B711 }, + { (char*) "Hongkong" , 0x04B78C }, + { (char*) "HST" , 0x04BA9F }, + { (char*) "Iceland" , 0x04BB88 }, + { (char*) "Indian/Antananarivo" , 0x04BC16 }, + { (char*) "Indian/Chagos" , 0x04BCC2 }, + { (char*) "Indian/Christmas" , 0x04BD66 }, + { (char*) "Indian/Cocos" , 0x04BDF7 }, + { (char*) "Indian/Comoro" , 0x04BE8F }, + { (char*) "Indian/Kerguelen" , 0x04BF1E }, + { (char*) "Indian/Mahe" , 0x04BFAF }, + { (char*) "Indian/Maldives" , 0x04C040 }, + { (char*) "Indian/Mauritius" , 0x04C0E4 }, + { (char*) "Indian/Mayotte" , 0x04C1A3 }, + { (char*) "Indian/Reunion" , 0x04C232 }, + { (char*) "Iran" , 0x04C2C3 }, + { (char*) "Israel" , 0x04C5FB }, + { (char*) "Jamaica" , 0x04CA39 }, + { (char*) "Japan" , 0x04CB98 }, + { (char*) "Kwajalein" , 0x04CC79 }, + { (char*) "Libya" , 0x04CD60 }, + { (char*) "MET" , 0x04CF1B }, + { (char*) "Mexico/BajaNorte" , 0x04D376 }, + { (char*) "Mexico/BajaSur" , 0x04D7B9 }, + { (char*) "Mexico/General" , 0x04DA77 }, + { (char*) "MST" , 0x04DD88 }, + { (char*) "MST7MDT" , 0x04DE84 }, + { (char*) "Navajo" , 0x04E2A2 }, + { (char*) "NZ" , 0x04E6C0 }, + { (char*) "NZ-CHAT" , 0x04EADF }, + { (char*) "Pacific/Apia" , 0x04EE13 }, + { (char*) "Pacific/Auckland" , 0x04EFB6 }, + { (char*) "Pacific/Bougainville" , 0x04F3E8 }, + { (char*) "Pacific/Chatham" , 0x04F4C9 }, + { (char*) "Pacific/Chuuk" , 0x04F80C }, + { (char*) "Pacific/Easter" , 0x04F8EA }, + { (char*) "Pacific/Efate" , 0x04FD99 }, + { (char*) "Pacific/Enderbury" , 0x04FEFB }, + { (char*) "Pacific/Fakaofo" , 0x04FFB3 }, + { (char*) "Pacific/Fiji" , 0x050058 }, + { (char*) "Pacific/Funafuti" , 0x0501F0 }, + { (char*) "Pacific/Galapagos" , 0x050282 }, + { (char*) "Pacific/Gambier" , 0x05034E }, + { (char*) "Pacific/Guadalcanal" , 0x0503ED }, + { (char*) "Pacific/Guam" , 0x05047F }, + { (char*) "Pacific/Honolulu" , 0x0505E9 }, + { (char*) "Pacific/Johnston" , 0x0506D8 }, + { (char*) "Pacific/Kanton" , 0x0507C1 }, + { (char*) "Pacific/Kiritimati" , 0x050888 }, + { (char*) "Pacific/Kosrae" , 0x05094E }, + { (char*) "Pacific/Kwajalein" , 0x050A52 }, + { (char*) "Pacific/Majuro" , 0x050B42 }, + { (char*) "Pacific/Marquesas" , 0x050C40 }, + { (char*) "Pacific/Midway" , 0x050CE8 }, + { (char*) "Pacific/Nauru" , 0x050DAB }, + { (char*) "Pacific/Niue" , 0x050E6E }, + { (char*) "Pacific/Norfolk" , 0x050F14 }, + { (char*) "Pacific/Noumea" , 0x05100D }, + { (char*) "Pacific/Pago_Pago" , 0x0510DF }, + { (char*) "Pacific/Palau" , 0x05117D }, + { (char*) "Pacific/Pitcairn" , 0x05121D }, + { (char*) "Pacific/Pohnpei" , 0x0512C2 }, + { (char*) "Pacific/Ponape" , 0x0513B2 }, + { (char*) "Pacific/Port_Moresby" , 0x051444 }, + { (char*) "Pacific/Rarotonga" , 0x051502 }, + { (char*) "Pacific/Saipan" , 0x0516A4 }, + { (char*) "Pacific/Samoa" , 0x051805 }, + { (char*) "Pacific/Tahiti" , 0x0518A3 }, + { (char*) "Pacific/Tarawa" , 0x051943 }, + { (char*) "Pacific/Tongatapu" , 0x0519E4 }, + { (char*) "Pacific/Truk" , 0x051ADD }, + { (char*) "Pacific/Wake" , 0x051B83 }, + { (char*) "Pacific/Wallis" , 0x051C20 }, + { (char*) "Pacific/Yap" , 0x051CB2 }, + { (char*) "Poland" , 0x051D58 }, + { (char*) "Portugal" , 0x0520FF }, + { (char*) "PRC" , 0x0526C2 }, + { (char*) "PST8PDT" , 0x052857 }, + { (char*) "ROC" , 0x052D71 }, + { (char*) "ROK" , 0x052F7C }, + { (char*) "Singapore" , 0x053127 }, + { (char*) "Turkey" , 0x053233 }, + { (char*) "UCT" , 0x0536EF }, + { (char*) "Universal" , 0x05376A }, + { (char*) "US/Alaska" , 0x0537E5 }, + { (char*) "US/Aleutian" , 0x053BC2 }, + { (char*) "US/Arizona" , 0x053F97 }, + { (char*) "US/Central" , 0x054093 }, + { (char*) "US/East-Indiana" , 0x054779 }, + { (char*) "US/Eastern" , 0x054998 }, + { (char*) "US/Hawaii" , 0x055074 }, + { (char*) "US/Indiana-Starke" , 0x05515D }, + { (char*) "US/Michigan" , 0x055561 }, + { (char*) "US/Mountain" , 0x0558F0 }, + { (char*) "US/Pacific" , 0x055D0E }, + { (char*) "US/Samoa" , 0x056228 }, + { (char*) "UTC" , 0x0562C6 }, + { (char*) "W-SU" , 0x056341 }, + { (char*) "WET" , 0x0566D9 }, + { (char*) "Zulu" , 0x056C9C }, }; -const unsigned char timelib_timezone_db_data_builtin[354224] = { +const unsigned char timelib_timezone_db_data_builtin[355607] = { /* Africa/Abidjan */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3709,6 +3710,95 @@ const unsigned char timelib_timezone_db_data_builtin[354224] = { 0x54, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36, 0x0A, 0x00, 0x98, 0x7C, 0x75, 0x00, 0x92, 0x5B, 0x72, 0x00, 0x00, 0x00, 0x00, +/* America/Coyhaique */ +0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 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, 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, 0x85, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0xFF, +0xFF, 0xFF, 0xFF, 0x69, 0x87, 0x1F, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x30, 0x47, 0x45, 0xFF, +0xFF, 0xFF, 0xFF, 0x9B, 0x5C, 0xE5, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0x7C, 0xE2, 0xC5, 0xFF, +0xFF, 0xFF, 0xFF, 0xA1, 0x00, 0x71, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x5E, 0x77, 0xC5, 0xFF, +0xFF, 0xFF, 0xFF, 0xB1, 0x77, 0x3D, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2, 0x41, 0x00, 0xD0, 0xFF, +0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x70, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0x22, 0x34, 0x50, 0xFF, +0xFF, 0xFF, 0xFF, 0xB5, 0x39, 0xA4, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x03, 0x67, 0xD0, 0xFF, +0xFF, 0xFF, 0xFF, 0xB7, 0x1A, 0xD7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xE4, 0x9B, 0x50, 0xFF, +0xFF, 0xFF, 0xFF, 0xB8, 0xFD, 0x5C, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xB9, 0xC7, 0x20, 0x50, 0xFF, +0xFF, 0xFF, 0xFF, 0xCC, 0x1C, 0x6E, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x6C, 0xE7, 0xD0, 0xFF, +0xFF, 0xFF, 0xFF, 0xD4, 0x17, 0xE3, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x33, 0x55, 0xC0, 0xFF, +0xFF, 0xFF, 0xFF, 0xD5, 0x76, 0x92, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xD1, 0x3C, 0x40, 0xFF, +0xFF, 0xFF, 0xFF, 0xFE, 0x92, 0xFA, 0xB0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCD, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x00, 0x72, 0xDC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x75, 0x50, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x02, 0x40, 0x49, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x55, 0x32, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x04, 0x20, 0x2B, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x3E, 0x4F, 0x40, 0x00, +0x00, 0x00, 0x00, 0x06, 0x00, 0x0D, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0B, 0xBC, 0x40, 0x00, +0x00, 0x00, 0x00, 0x07, 0xDF, 0xEF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFE, 0x13, 0x40, 0x00, +0x00, 0x00, 0x00, 0x09, 0xBF, 0xD1, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xDD, 0xF5, 0x40, 0x00, +0x00, 0x00, 0x00, 0x0B, 0xA8, 0xEE, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xBD, 0xD7, 0x40, 0x00, +0x00, 0x00, 0x00, 0x0D, 0x88, 0xD0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x9D, 0xB9, 0x40, 0x00, +0x00, 0x00, 0x00, 0x0F, 0x68, 0xB2, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xD5, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x11, 0x48, 0x94, 0x30, 0x00, 0x00, 0x00, 0x00, 0x12, 0x66, 0xB7, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x13, 0x28, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x14, 0x46, 0x99, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x15, 0x11, 0x92, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x26, 0x7B, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x16, 0xF1, 0x74, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x5D, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x18, 0xD1, 0x56, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x19, 0xE6, 0x3F, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x1A, 0xB1, 0x38, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xCF, 0x5C, 0x40, 0x00, +0x00, 0x00, 0x00, 0x1C, 0x91, 0x1A, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xAF, 0x3E, 0x40, 0x00, +0x00, 0x00, 0x00, 0x1E, 0x70, 0xFC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x8F, 0x20, 0x40, 0x00, +0x00, 0x00, 0x00, 0x20, 0x7F, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x21, 0x6F, 0x02, 0x40, 0x00, +0x00, 0x00, 0x00, 0x22, 0x39, 0xFB, 0x30, 0x00, 0x00, 0x00, 0x00, 0x23, 0x4E, 0xE4, 0x40, 0x00, +0x00, 0x00, 0x00, 0x24, 0x19, 0xDD, 0x30, 0x00, 0x00, 0x00, 0x00, 0x25, 0x38, 0x00, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x25, 0xF9, 0xBF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x26, 0xF2, 0xF8, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x27, 0xD9, 0xA1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x28, 0xF7, 0xC4, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x29, 0xC2, 0xBD, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD7, 0xA6, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x2B, 0xA2, 0x9F, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xB7, 0x88, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x2D, 0x82, 0x81, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x97, 0x6A, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x2F, 0x62, 0x63, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0x87, 0x40, 0x00, +0x00, 0x00, 0x00, 0x31, 0x42, 0x45, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x32, 0x60, 0x69, 0x40, 0x00, +0x00, 0x00, 0x00, 0x33, 0x3D, 0xD7, 0x30, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40, 0x4B, 0x40, 0x00, +0x00, 0x00, 0x00, 0x35, 0x0B, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x36, 0x0D, 0xB8, 0x40, 0x00, +0x00, 0x00, 0x00, 0x37, 0x06, 0xD5, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0F, 0x40, 0x00, +0x00, 0x00, 0x00, 0x38, 0xCB, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x39, 0xE9, 0x2B, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x3A, 0xAA, 0xEA, 0x30, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xC9, 0x0D, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x3C, 0x8A, 0xCC, 0x30, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xA8, 0xEF, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x3E, 0x6A, 0xAE, 0x30, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x88, 0xD1, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x40, 0x53, 0xCA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x68, 0xB3, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x42, 0x33, 0xAC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x95, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x44, 0x13, 0x8E, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x31, 0xB2, 0x40, 0x00, +0x00, 0x00, 0x00, 0x45, 0xF3, 0x70, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x47, 0x11, 0x94, 0x40, 0x00, +0x00, 0x00, 0x00, 0x47, 0xEF, 0x02, 0x30, 0x00, 0x00, 0x00, 0x00, 0x48, 0xF1, 0x76, 0x40, 0x00, +0x00, 0x00, 0x00, 0x49, 0xBC, 0x6F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xD1, 0x58, 0x40, 0x00, +0x00, 0x00, 0x00, 0x4B, 0xB8, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xB1, 0x3A, 0x40, 0x00, +0x00, 0x00, 0x00, 0x4D, 0xC6, 0x07, 0x30, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x50, 0x82, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x4F, 0x9C, 0xAE, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x42, 0xD9, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x51, 0x7C, 0x90, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x2B, 0xF6, 0x40, 0x00, +0x00, 0x00, 0x00, 0x53, 0x5C, 0x72, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x0B, 0xD8, 0x40, 0x00, +0x00, 0x00, 0x00, 0x57, 0x37, 0xE6, 0x30, 0x00, 0x00, 0x00, 0x00, 0x57, 0xAF, 0xEC, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x59, 0x17, 0xC8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x59, 0x8F, 0xCE, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x5A, 0xF7, 0xAA, 0x30, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x6F, 0xB0, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x5C, 0xA9, 0x67, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x74, 0x7C, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x5E, 0x89, 0x49, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x54, 0x5E, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x60, 0x69, 0x2B, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x34, 0x40, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x62, 0x49, 0x0D, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x1D, 0x5D, 0x40, 0x00, +0x00, 0x00, 0x00, 0x64, 0x28, 0xEF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x64, 0xF4, 0x04, 0xC0, 0x00, +0x00, 0x00, 0x00, 0x66, 0x12, 0x0C, 0x30, 0x00, 0x00, 0x00, 0x00, 0x66, 0xDD, 0x21, 0x40, 0x00, +0x00, 0x00, 0x00, 0x67, 0xDB, 0x84, 0xB0, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x02, 0x04, 0x02, +0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x03, 0x02, 0x03, 0x04, 0x02, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, +0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x06, 0xFF, 0xFF, 0xBC, 0x70, +0x00, 0x00, 0xFF, 0xFF, 0xBD, 0xBB, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, +0xC7, 0xC0, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, +0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x4D, 0x54, 0x00, 0x2D, 0x30, +0x35, 0x00, 0x2D, 0x30, 0x34, 0x00, 0x2D, 0x30, 0x33, 0x00, 0x0A, 0x3C, 0x2D, 0x30, 0x33, 0x3E, +0x33, 0x0A, 0x00, 0x43, 0xCC, 0xC5, 0x00, 0xA4, 0xB1, 0x75, 0x00, 0x00, 0x00, 0x0C, 0x41, 0x79, +0x73, 0x65, 0x6E, 0x20, 0x52, 0x65, 0x67, 0x69, 0x6F, 0x6E, + /* America/Creston */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -7899,9 +7989,8 @@ const unsigned char timelib_timezone_db_data_builtin[354224] = { 0xC7, 0xC0, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x35, 0x00, 0x2D, 0x30, 0x34, 0x00, 0x2D, 0x30, 0x33, 0x00, 0x0A, 0x3C, 0x2D, 0x30, 0x33, 0x3E, -0x33, 0x0A, 0x00, 0x38, 0x3A, 0x88, 0x00, 0xA6, 0x72, 0xAD, 0x00, 0x00, 0x00, 0x14, 0x52, 0x65, -0x67, 0x69, 0x6F, 0x6E, 0x20, 0x6F, 0x66, 0x20, 0x4D, 0x61, 0x67, 0x61, 0x6C, 0x6C, 0x61, 0x6E, -0x65, 0x73, +0x33, 0x0A, 0x00, 0x38, 0x3A, 0x88, 0x00, 0xA6, 0x72, 0xAD, 0x00, 0x00, 0x00, 0x11, 0x4D, 0x61, +0x67, 0x61, 0x6C, 0x6C, 0x61, 0x6E, 0x65, 0x73, 0x20, 0x52, 0x65, 0x67, 0x69, 0x6F, 0x6E, /* America/Rainy_River */ 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13146,7 +13235,7 @@ const unsigned char timelib_timezone_db_data_builtin[354224] = { 0xFF, 0xFF, 0xFF, 0x9A, 0x6C, 0x7D, 0xC8, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xCC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x94, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAD, 0x13, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x79, 0x73, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0xCA, 0xC0, 0x00, -0x00, 0x00, 0x00, 0x10, 0xED, 0x3A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x11, 0xAD, 0xBC, 0x48, 0x00, +0x00, 0x00, 0x00, 0x10, 0xA9, 0xFD, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x11, 0xAD, 0xBC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x45, 0x4A, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37, 0xEC, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2D, 0x15, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x28, 0x20, 0x76, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x28, 0xDB, 0x9D, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x29, 0xCB, 0x9C, 0xC8, 0x00, @@ -21311,7 +21400,7 @@ const unsigned char timelib_timezone_db_data_builtin[354224] = { 0xFF, 0xFF, 0xFF, 0x9A, 0x6C, 0x7D, 0xC8, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xCC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x94, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAD, 0x13, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x79, 0x73, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0xCA, 0xC0, 0x00, -0x00, 0x00, 0x00, 0x10, 0xED, 0x3A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x11, 0xAD, 0xBC, 0x48, 0x00, +0x00, 0x00, 0x00, 0x10, 0xA9, 0xFD, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x11, 0xAD, 0xBC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x45, 0x4A, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37, 0xEC, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2D, 0x15, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x28, 0x20, 0x76, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x28, 0xDB, 0x9D, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x29, 0xCB, 0x9C, 0xC8, 0x00, @@ -24240,7 +24329,7 @@ const unsigned char timelib_timezone_db_data_builtin[354224] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; #else -const timelib_tzdb_index_entry timezonedb_idx_builtin[597] = { +const timelib_tzdb_index_entry timezonedb_idx_builtin[598] = { { (char*) "Africa/Abidjan" , 0x000000 }, { (char*) "Africa/Accra" , 0x0000A0 }, { (char*) "Africa/Addis_Ababa" , 0x0004D0 }, @@ -24340,508 +24429,509 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[597] = { { (char*) "America/Coral_Harbour" , 0x0114AF }, { (char*) "America/Cordoba" , 0x011571 }, { (char*) "America/Costa_Rica" , 0x0119A3 }, - { (char*) "America/Creston" , 0x011AEB }, - { (char*) "America/Cuiaba" , 0x011BD9 }, - { (char*) "America/Curacao" , 0x01216A }, - { (char*) "America/Danmarkshavn" , 0x012230 }, - { (char*) "America/Dawson" , 0x012510 }, - { (char*) "America/Dawson_Creek" , 0x012B7C }, - { (char*) "America/Denver" , 0x012FC2 }, - { (char*) "America/Detroit" , 0x01397F }, - { (char*) "America/Dominica" , 0x01425A }, - { (char*) "America/Edmonton" , 0x0142FA }, - { (char*) "America/Eirunepe" , 0x014C44 }, - { (char*) "America/El_Salvador" , 0x014EE1 }, - { (char*) "America/Ensenada" , 0x014FCD }, - { (char*) "America/Fort_Nelson" , 0x015973 }, - { (char*) "America/Fort_Wayne" , 0x016253 }, - { (char*) "America/Fortaleza" , 0x0168F1 }, - { (char*) "America/Glace_Bay" , 0x016BE1 }, - { (char*) "America/Godthab" , 0x017498 }, - { (char*) "America/Goose_Bay" , 0x017C05 }, - { (char*) "America/Grand_Turk" , 0x0188BB }, - { (char*) "America/Grenada" , 0x018FF1 }, - { (char*) "America/Guadeloupe" , 0x019091 }, - { (char*) "America/Guatemala" , 0x019131 }, - { (char*) "America/Guayaquil" , 0x019255 }, - { (char*) "America/Guyana" , 0x01935B }, - { (char*) "America/Halifax" , 0x01945F }, - { (char*) "America/Havana" , 0x01A1E9 }, - { (char*) "America/Hermosillo" , 0x01AB65 }, - { (char*) "America/Indiana/Indianapolis" , 0x01ACFB }, - { (char*) "America/Indiana/Knox" , 0x01B3B2 }, - { (char*) "America/Indiana/Marengo" , 0x01BD5F }, - { (char*) "America/Indiana/Petersburg" , 0x01C44C }, - { (char*) "America/Indiana/Tell_City" , 0x01CBEB }, - { (char*) "America/Indiana/Vevay" , 0x01D2AF }, - { (char*) "America/Indiana/Vincennes" , 0x01D86B }, - { (char*) "America/Indiana/Winamac" , 0x01DF41 }, - { (char*) "America/Indianapolis" , 0x01E665 }, - { (char*) "America/Inuvik" , 0x01ED03 }, - { (char*) "America/Iqaluit" , 0x01F53D }, - { (char*) "America/Jamaica" , 0x01FDFC }, - { (char*) "America/Jujuy" , 0x01FFEA }, - { (char*) "America/Juneau" , 0x020400 }, - { (char*) "America/Kentucky/Louisville" , 0x020D51 }, - { (char*) "America/Kentucky/Monticello" , 0x02185F }, - { (char*) "America/Knox_IN" , 0x0221BF }, - { (char*) "America/Kralendijk" , 0x022B57 }, - { (char*) "America/La_Paz" , 0x022C59 }, - { (char*) "America/Lima" , 0x022D3F }, - { (char*) "America/Los_Angeles" , 0x022ED3 }, - { (char*) "America/Louisville" , 0x023A0A }, - { (char*) "America/Lower_Princes" , 0x0244FA }, - { (char*) "America/Maceio" , 0x0245FC }, - { (char*) "America/Managua" , 0x0248F2 }, - { (char*) "America/Manaus" , 0x024AAC }, - { (char*) "America/Marigot" , 0x024D15 }, - { (char*) "America/Martinique" , 0x024E17 }, - { (char*) "America/Matamoros" , 0x024F0B }, - { (char*) "America/Mazatlan" , 0x0254CD }, - { (char*) "America/Mendoza" , 0x02592F }, - { (char*) "America/Menominee" , 0x025D61 }, - { (char*) "America/Merida" , 0x02666E }, - { (char*) "America/Metlakatla" , 0x026A77 }, - { (char*) "America/Mexico_City" , 0x027029 }, - { (char*) "America/Miquelon" , 0x027509 }, - { (char*) "America/Moncton" , 0x027B89 }, - { (char*) "America/Monterrey" , 0x0287FF }, - { (char*) "America/Montevideo" , 0x028C9B }, - { (char*) "America/Montreal" , 0x02927F }, - { (char*) "America/Montserrat" , 0x02A031 }, - { (char*) "America/Nassau" , 0x02A0D1 }, - { (char*) "America/New_York" , 0x02AA31 }, - { (char*) "America/Nipigon" , 0x02B831 }, - { (char*) "America/Nome" , 0x02C5E3 }, - { (char*) "America/Noronha" , 0x02CF3B }, - { (char*) "America/North_Dakota/Beulah" , 0x02D215 }, - { (char*) "America/North_Dakota/Center" , 0x02DB92 }, - { (char*) "America/North_Dakota/New_Salem" , 0x02E50F }, - { (char*) "America/Nuuk" , 0x02EE92 }, - { (char*) "America/Ojinaga" , 0x02F610 }, - { (char*) "America/Panama" , 0x02FC2C }, - { (char*) "America/Pangnirtung" , 0x02FCEE }, - { (char*) "America/Paramaribo" , 0x030594 }, - { (char*) "America/Phoenix" , 0x030698 }, - { (char*) "America/Port-au-Prince" , 0x030824 }, - { (char*) "America/Port_of_Spain" , 0x030DCA }, - { (char*) "America/Porto_Acre" , 0x030E6A }, - { (char*) "America/Porto_Velho" , 0x0310DC }, - { (char*) "America/Puerto_Rico" , 0x031322 }, - { (char*) "America/Punta_Arenas" , 0x031424 }, - { (char*) "America/Rainy_River" , 0x031BB2 }, - { (char*) "America/Rankin_Inlet" , 0x0326F2 }, - { (char*) "America/Recife" , 0x032F26 }, - { (char*) "America/Regina" , 0x0331FA }, - { (char*) "America/Resolute" , 0x0335EF }, - { (char*) "America/Rio_Branco" , 0x033E24 }, - { (char*) "America/Rosario" , 0x03409A }, - { (char*) "America/Santa_Isabel" , 0x0344CC }, - { (char*) "America/Santarem" , 0x034E72 }, - { (char*) "America/Santiago" , 0x0350D5 }, - { (char*) "America/Santo_Domingo" , 0x035AC1 }, - { (char*) "America/Sao_Paulo" , 0x035C97 }, - { (char*) "America/Scoresbysund" , 0x03626F }, - { (char*) "America/Shiprock" , 0x036A27 }, - { (char*) "America/Sitka" , 0x0373CF }, - { (char*) "America/St_Barthelemy" , 0x037D07 }, - { (char*) "America/St_Johns" , 0x037E09 }, - { (char*) "America/St_Kitts" , 0x038C77 }, - { (char*) "America/St_Lucia" , 0x038D17 }, - { (char*) "America/St_Thomas" , 0x038DD9 }, - { (char*) "America/St_Vincent" , 0x038E79 }, - { (char*) "America/Swift_Current" , 0x038F3B }, - { (char*) "America/Tegucigalpa" , 0x039189 }, - { (char*) "America/Thule" , 0x039291 }, - { (char*) "America/Thunder_Bay" , 0x039889 }, - { (char*) "America/Tijuana" , 0x03A63B }, - { (char*) "America/Toronto" , 0x03AFF0 }, - { (char*) "America/Tortola" , 0x03BDC0 }, - { (char*) "America/Vancouver" , 0x03BE60 }, - { (char*) "America/Virgin" , 0x03C9D1 }, - { (char*) "America/Whitehorse" , 0x03CAD3 }, - { (char*) "America/Winnipeg" , 0x03D13F }, - { (char*) "America/Yakutat" , 0x03DC9C }, - { (char*) "America/Yellowknife" , 0x03E5B9 }, - { (char*) "Antarctica/Casey" , 0x03EEE1 }, - { (char*) "Antarctica/Davis" , 0x03F099 }, - { (char*) "Antarctica/DumontDUrville" , 0x03F1C5 }, - { (char*) "Antarctica/Macquarie" , 0x03F295 }, - { (char*) "Antarctica/Mawson" , 0x03FB85 }, - { (char*) "Antarctica/McMurdo" , 0x03FC50 }, - { (char*) "Antarctica/Palmer" , 0x04044B }, - { (char*) "Antarctica/Rothera" , 0x0409D9 }, - { (char*) "Antarctica/South_Pole" , 0x040A82 }, - { (char*) "Antarctica/Syowa" , 0x041413 }, - { (char*) "Antarctica/Troll" , 0x0414BB }, - { (char*) "Antarctica/Vostok" , 0x041948 }, - { (char*) "Arctic/Longyearbyen" , 0x041A2F }, - { (char*) "Asia/Aden" , 0x042335 }, - { (char*) "Asia/Almaty" , 0x0423D8 }, - { (char*) "Asia/Amman" , 0x0427CD }, - { (char*) "Asia/Anadyr" , 0x042D72 }, - { (char*) "Asia/Aqtau" , 0x043227 }, - { (char*) "Asia/Aqtobe" , 0x043611 }, - { (char*) "Asia/Ashgabat" , 0x043A0F }, - { (char*) "Asia/Ashkhabad" , 0x043C78 }, - { (char*) "Asia/Atyrau" , 0x043EE1 }, - { (char*) "Asia/Baghdad" , 0x0442D3 }, - { (char*) "Asia/Bahrain" , 0x0446A8 }, - { (char*) "Asia/Baku" , 0x044793 }, - { (char*) "Asia/Bangkok" , 0x044C5C }, - { (char*) "Asia/Barnaul" , 0x044D21 }, - { (char*) "Asia/Beirut" , 0x0451F2 }, - { (char*) "Asia/Bishkek" , 0x045A68 }, - { (char*) "Asia/Brunei" , 0x045E3D }, - { (char*) "Asia/Calcutta" , 0x045F06 }, - { (char*) "Asia/Chita" , 0x04602F }, - { (char*) "Asia/Choibalsan" , 0x046506 }, - { (char*) "Asia/Chongqing" , 0x04687F }, - { (char*) "Asia/Chungking" , 0x046ABC }, - { (char*) "Asia/Colombo" , 0x046CF9 }, - { (char*) "Asia/Dacca" , 0x046E6B }, - { (char*) "Asia/Damascus" , 0x046FBA }, - { (char*) "Asia/Dhaka" , 0x047717 }, - { (char*) "Asia/Dili" , 0x047866 }, - { (char*) "Asia/Dubai" , 0x047973 }, - { (char*) "Asia/Dushanbe" , 0x047A16 }, - { (char*) "Asia/Famagusta" , 0x047C63 }, - { (char*) "Asia/Gaza" , 0x04846A }, - { (char*) "Asia/Harbin" , 0x049384 }, - { (char*) "Asia/Hebron" , 0x0495C1 }, - { (char*) "Asia/Ho_Chi_Minh" , 0x04A4F6 }, - { (char*) "Asia/Hong_Kong" , 0x04A653 }, - { (char*) "Asia/Hovd" , 0x04AB30 }, - { (char*) "Asia/Irkutsk" , 0x04AEBF }, - { (char*) "Asia/Istanbul" , 0x04B3B2 }, - { (char*) "Asia/Jakarta" , 0x04BB4B }, - { (char*) "Asia/Jayapura" , 0x04BCE3 }, - { (char*) "Asia/Jerusalem" , 0x04BE02 }, - { (char*) "Asia/Kabul" , 0x04C762 }, - { (char*) "Asia/Kamchatka" , 0x04C830 }, - { (char*) "Asia/Karachi" , 0x04CCCE }, - { (char*) "Asia/Kashgar" , 0x04CE55 }, - { (char*) "Asia/Kathmandu" , 0x04CEF8 }, - { (char*) "Asia/Katmandu" , 0x04CFCA }, - { (char*) "Asia/Khandyga" , 0x04D09C }, - { (char*) "Asia/Kolkata" , 0x04D5AF }, - { (char*) "Asia/Krasnoyarsk" , 0x04D6D8 }, - { (char*) "Asia/Kuala_Lumpur" , 0x04DBA6 }, - { (char*) "Asia/Kuching" , 0x04DD57 }, - { (char*) "Asia/Kuwait" , 0x04DF46 }, - { (char*) "Asia/Macao" , 0x04DFE9 }, - { (char*) "Asia/Macau" , 0x04E4C0 }, - { (char*) "Asia/Magadan" , 0x04E997 }, - { (char*) "Asia/Makassar" , 0x04EE6B }, - { (char*) "Asia/Manila" , 0x04EFBE }, - { (char*) "Asia/Muscat" , 0x04F170 }, - { (char*) "Asia/Nicosia" , 0x04F213 }, - { (char*) "Asia/Novokuznetsk" , 0x04F9FF }, - { (char*) "Asia/Novosibirsk" , 0x04FE9B }, - { (char*) "Asia/Omsk" , 0x050372 }, - { (char*) "Asia/Oral" , 0x050834 }, - { (char*) "Asia/Phnom_Penh" , 0x050C2E }, - { (char*) "Asia/Pontianak" , 0x050D53 }, - { (char*) "Asia/Pyongyang" , 0x050ED6 }, - { (char*) "Asia/Qatar" , 0x050FCF }, - { (char*) "Asia/Qostanay" , 0x051094 }, - { (char*) "Asia/Qyzylorda" , 0x0514BB }, - { (char*) "Asia/Rangoon" , 0x0518D7 }, - { (char*) "Asia/Riyadh" , 0x0519E1 }, - { (char*) "Asia/Saigon" , 0x051A84 }, - { (char*) "Asia/Sakhalin" , 0x051BE1 }, - { (char*) "Asia/Samarkand" , 0x0520A9 }, - { (char*) "Asia/Seoul" , 0x0522F9 }, - { (char*) "Asia/Shanghai" , 0x05256E }, - { (char*) "Asia/Singapore" , 0x0527B7 }, - { (char*) "Asia/Srednekolymsk" , 0x052954 }, - { (char*) "Asia/Taipei" , 0x052E28 }, - { (char*) "Asia/Tashkent" , 0x05312D }, - { (char*) "Asia/Tbilisi" , 0x05338B }, - { (char*) "Asia/Tehran" , 0x053794 }, - { (char*) "Asia/Tel_Aviv" , 0x053C80 }, - { (char*) "Asia/Thimbu" , 0x0545E0 }, - { (char*) "Asia/Thimphu" , 0x0546A9 }, - { (char*) "Asia/Tokyo" , 0x054772 }, - { (char*) "Asia/Tomsk" , 0x0548B3 }, - { (char*) "Asia/Ujung_Pandang" , 0x054D84 }, - { (char*) "Asia/Ulaanbaatar" , 0x054E8E }, - { (char*) "Asia/Ulan_Bator" , 0x055217 }, - { (char*) "Asia/Urumqi" , 0x055590 }, - { (char*) "Asia/Ust-Nera" , 0x055640 }, - { (char*) "Asia/Vientiane" , 0x055B36 }, - { (char*) "Asia/Vladivostok" , 0x055C77 }, - { (char*) "Asia/Yakutsk" , 0x056140 }, - { (char*) "Asia/Yangon" , 0x056608 }, - { (char*) "Asia/Yekaterinburg" , 0x056712 }, - { (char*) "Asia/Yerevan" , 0x056BF9 }, - { (char*) "Atlantic/Azores" , 0x057076 }, - { (char*) "Atlantic/Bermuda" , 0x057DFA }, - { (char*) "Atlantic/Canary" , 0x058762 }, - { (char*) "Atlantic/Cape_Verde" , 0x058EE5 }, - { (char*) "Atlantic/Faeroe" , 0x058FF1 }, - { (char*) "Atlantic/Faroe" , 0x059714 }, - { (char*) "Atlantic/Jan_Mayen" , 0x059E37 }, - { (char*) "Atlantic/Madeira" , 0x05A73D }, - { (char*) "Atlantic/Reykjavik" , 0x05B489 }, - { (char*) "Atlantic/South_Georgia" , 0x05B91F }, - { (char*) "Atlantic/St_Helena" , 0x05B9C1 }, - { (char*) "Atlantic/Stanley" , 0x05BA83 }, - { (char*) "Australia/ACT" , 0x05BF3F }, - { (char*) "Australia/Adelaide" , 0x05C7D9 }, - { (char*) "Australia/Brisbane" , 0x05D094 }, - { (char*) "Australia/Broken_Hill" , 0x05D25A }, - { (char*) "Australia/Canberra" , 0x05DB37 }, - { (char*) "Australia/Currie" , 0x05E3D1 }, - { (char*) "Australia/Darwin" , 0x05ED13 }, - { (char*) "Australia/Eucla" , 0x05EE76 }, - { (char*) "Australia/Hobart" , 0x05F063 }, - { (char*) "Australia/LHI" , 0x05F9AD }, - { (char*) "Australia/Lindeman" , 0x0600EF }, - { (char*) "Australia/Lord_Howe" , 0x0602F5 }, - { (char*) "Australia/Melbourne" , 0x060A47 }, - { (char*) "Australia/North" , 0x0612E9 }, - { (char*) "Australia/NSW" , 0x06143A }, - { (char*) "Australia/Perth" , 0x061CD4 }, - { (char*) "Australia/Queensland" , 0x061EBC }, - { (char*) "Australia/South" , 0x06206B }, - { (char*) "Australia/Sydney" , 0x062917 }, - { (char*) "Australia/Tasmania" , 0x0631CD }, - { (char*) "Australia/Victoria" , 0x063B0F }, - { (char*) "Australia/West" , 0x0643A9 }, - { (char*) "Australia/Yancowinna" , 0x064573 }, - { (char*) "Brazil/Acre" , 0x064E34 }, - { (char*) "Brazil/DeNoronha" , 0x0650A6 }, - { (char*) "Brazil/East" , 0x065370 }, - { (char*) "Brazil/West" , 0x065912 }, - { (char*) "Canada/Atlantic" , 0x065B6C }, - { (char*) "Canada/Central" , 0x0668D8 }, - { (char*) "Canada/Eastern" , 0x067418 }, - { (char*) "Canada/Mountain" , 0x0681CA }, - { (char*) "Canada/Newfoundland" , 0x068AF2 }, - { (char*) "Canada/Pacific" , 0x069945 }, - { (char*) "Canada/Saskatchewan" , 0x06A49D }, - { (char*) "Canada/Yukon" , 0x06A87D }, - { (char*) "CET" , 0x06AED7 }, - { (char*) "Chile/Continental" , 0x06BA58 }, - { (char*) "Chile/EasterIsland" , 0x06C437 }, - { (char*) "CST6CDT" , 0x06CCEE }, - { (char*) "Cuba" , 0x06DB02 }, - { (char*) "EET" , 0x06E47E }, - { (char*) "Egypt" , 0x06ED60 }, - { (char*) "Eire" , 0x06F6CB }, - { (char*) "EST" , 0x07047B }, - { (char*) "EST5EDT" , 0x07053D }, - { (char*) "Etc/GMT" , 0x071329 }, - { (char*) "Etc/GMT+0" , 0x0713A7 }, - { (char*) "Etc/GMT+1" , 0x071425 }, - { (char*) "Etc/GMT+10" , 0x0714A5 }, - { (char*) "Etc/GMT+11" , 0x071526 }, - { (char*) "Etc/GMT+12" , 0x0715A7 }, - { (char*) "Etc/GMT+2" , 0x071628 }, - { (char*) "Etc/GMT+3" , 0x0716A8 }, - { (char*) "Etc/GMT+4" , 0x071728 }, - { (char*) "Etc/GMT+5" , 0x0717A8 }, - { (char*) "Etc/GMT+6" , 0x071828 }, - { (char*) "Etc/GMT+7" , 0x0718A8 }, - { (char*) "Etc/GMT+8" , 0x071928 }, - { (char*) "Etc/GMT+9" , 0x0719A8 }, - { (char*) "Etc/GMT-0" , 0x071A28 }, - { (char*) "Etc/GMT-1" , 0x071AA6 }, - { (char*) "Etc/GMT-10" , 0x071B27 }, - { (char*) "Etc/GMT-11" , 0x071BA9 }, - { (char*) "Etc/GMT-12" , 0x071C2B }, - { (char*) "Etc/GMT-13" , 0x071CAD }, - { (char*) "Etc/GMT-14" , 0x071D2F }, - { (char*) "Etc/GMT-2" , 0x071DB1 }, - { (char*) "Etc/GMT-3" , 0x071E32 }, - { (char*) "Etc/GMT-4" , 0x071EB3 }, - { (char*) "Etc/GMT-5" , 0x071F34 }, - { (char*) "Etc/GMT-6" , 0x071FB5 }, - { (char*) "Etc/GMT-7" , 0x072036 }, - { (char*) "Etc/GMT-8" , 0x0720B7 }, - { (char*) "Etc/GMT-9" , 0x072138 }, - { (char*) "Etc/GMT0" , 0x0721B9 }, - { (char*) "Etc/Greenwich" , 0x072237 }, - { (char*) "Etc/UCT" , 0x0722B5 }, - { (char*) "Etc/Universal" , 0x072333 }, - { (char*) "Etc/UTC" , 0x0723B1 }, - { (char*) "Etc/Zulu" , 0x07242F }, - { (char*) "Europe/Amsterdam" , 0x0724AD }, - { (char*) "Europe/Andorra" , 0x073017 }, - { (char*) "Europe/Astrakhan" , 0x0736F1 }, - { (char*) "Europe/Athens" , 0x073B8E }, - { (char*) "Europe/Belfast" , 0x074470 }, - { (char*) "Europe/Belgrade" , 0x0752CC }, - { (char*) "Europe/Berlin" , 0x075A58 }, - { (char*) "Europe/Bratislava" , 0x07636D }, - { (char*) "Europe/Brussels" , 0x076C76 }, - { (char*) "Europe/Bucharest" , 0x0777F7 }, - { (char*) "Europe/Budapest" , 0x07808B }, - { (char*) "Europe/Busingen" , 0x0789D7 }, - { (char*) "Europe/Chisinau" , 0x079160 }, - { (char*) "Europe/Copenhagen" , 0x079AC2 }, - { (char*) "Europe/Dublin" , 0x07A327 }, - { (char*) "Europe/Gibraltar" , 0x07B0D7 }, - { (char*) "Europe/Guernsey" , 0x07BCDF }, - { (char*) "Europe/Helsinki" , 0x07CB7F }, - { (char*) "Europe/Isle_of_Man" , 0x07D2F7 }, - { (char*) "Europe/Istanbul" , 0x07E143 }, - { (char*) "Europe/Jersey" , 0x07E8DC }, - { (char*) "Europe/Kaliningrad" , 0x07F77C }, - { (char*) "Europe/Kiev" , 0x07FD71 }, - { (char*) "Europe/Kirov" , 0x0805C5 }, - { (char*) "Europe/Kyiv" , 0x080A80 }, - { (char*) "Europe/Lisbon" , 0x0812E3 }, - { (char*) "Europe/Ljubljana" , 0x0820C9 }, - { (char*) "Europe/London" , 0x082855 }, - { (char*) "Europe/Luxembourg" , 0x0836B1 }, - { (char*) "Europe/Madrid" , 0x08423F }, - { (char*) "Europe/Malta" , 0x084C91 }, - { (char*) "Europe/Mariehamn" , 0x0856D9 }, - { (char*) "Europe/Minsk" , 0x085E51 }, - { (char*) "Europe/Monaco" , 0x086378 }, - { (char*) "Europe/Moscow" , 0x086F04 }, - { (char*) "Europe/Nicosia" , 0x087523 }, - { (char*) "Europe/Oslo" , 0x087D01 }, - { (char*) "Europe/Paris" , 0x0885C1 }, - { (char*) "Europe/Podgorica" , 0x08915F }, - { (char*) "Europe/Prague" , 0x0898EB }, - { (char*) "Europe/Riga" , 0x08A1F4 }, - { (char*) "Europe/Rome" , 0x08AA96 }, - { (char*) "Europe/Samara" , 0x08B4F3 }, - { (char*) "Europe/San_Marino" , 0x08B9C9 }, - { (char*) "Europe/Sarajevo" , 0x08C426 }, - { (char*) "Europe/Saratov" , 0x08CBB2 }, - { (char*) "Europe/Simferopol" , 0x08D05F }, - { (char*) "Europe/Skopje" , 0x08D62E }, - { (char*) "Europe/Sofia" , 0x08DDBA }, - { (char*) "Europe/Stockholm" , 0x08E5E3 }, - { (char*) "Europe/Tallinn" , 0x08ED64 }, - { (char*) "Europe/Tirane" , 0x08F5D4 }, - { (char*) "Europe/Tiraspol" , 0x08FE04 }, - { (char*) "Europe/Ulyanovsk" , 0x090766 }, - { (char*) "Europe/Uzhgorod" , 0x090C69 }, - { (char*) "Europe/Vaduz" , 0x0914BD }, - { (char*) "Europe/Vatican" , 0x091C29 }, - { (char*) "Europe/Vienna" , 0x092686 }, - { (char*) "Europe/Vilnius" , 0x092F2A }, - { (char*) "Europe/Volgograd" , 0x0937A8 }, - { (char*) "Europe/Warsaw" , 0x093C6F }, - { (char*) "Europe/Zagreb" , 0x0946D9 }, - { (char*) "Europe/Zaporozhye" , 0x094E65 }, - { (char*) "Europe/Zurich" , 0x0956B9 }, - { (char*) "Factory" , 0x095E3A }, - { (char*) "GB" , 0x095EBA }, - { (char*) "GB-Eire" , 0x096D16 }, - { (char*) "GMT" , 0x097B72 }, - { (char*) "GMT+0" , 0x097BF0 }, - { (char*) "GMT-0" , 0x097C6E }, - { (char*) "GMT0" , 0x097CEC }, - { (char*) "Greenwich" , 0x097D6A }, - { (char*) "Hongkong" , 0x097DE8 }, - { (char*) "HST" , 0x0982C5 }, - { (char*) "Iceland" , 0x09841A }, - { (char*) "Indian/Antananarivo" , 0x0984BA }, - { (char*) "Indian/Chagos" , 0x0985A1 }, - { (char*) "Indian/Christmas" , 0x098666 }, - { (char*) "Indian/Cocos" , 0x098709 }, - { (char*) "Indian/Comoro" , 0x0987B5 }, - { (char*) "Indian/Kerguelen" , 0x098856 }, - { (char*) "Indian/Mahe" , 0x0988F9 }, - { (char*) "Indian/Maldives" , 0x09899C }, - { (char*) "Indian/Mauritius" , 0x098A61 }, - { (char*) "Indian/Mayotte" , 0x098B50 }, - { (char*) "Indian/Reunion" , 0x098BF1 }, - { (char*) "Iran" , 0x098C94 }, - { (char*) "Israel" , 0x099180 }, - { (char*) "Jamaica" , 0x099AE0 }, - { (char*) "Japan" , 0x099CCE }, - { (char*) "Kwajalein" , 0x099E0F }, - { (char*) "Libya" , 0x099F49 }, - { (char*) "MET" , 0x09A1C6 }, - { (char*) "Mexico/BajaNorte" , 0x09AD47 }, - { (char*) "Mexico/BajaSur" , 0x09B6ED }, - { (char*) "Mexico/General" , 0x09BB1D }, - { (char*) "MST" , 0x09BFEF }, - { (char*) "MST7MDT" , 0x09C163 }, - { (char*) "Navajo" , 0x09CB0B }, - { (char*) "NZ" , 0x09D4B3 }, - { (char*) "NZ-CHAT" , 0x09DE44 }, - { (char*) "Pacific/Apia" , 0x09E656 }, - { (char*) "Pacific/Auckland" , 0x09E8B8 }, - { (char*) "Pacific/Bougainville" , 0x09F25C }, - { (char*) "Pacific/Chatham" , 0x09F372 }, - { (char*) "Pacific/Chuuk" , 0x09FB93 }, - { (char*) "Pacific/Easter" , 0x09FCAD }, - { (char*) "Pacific/Efate" , 0x0A0571 }, - { (char*) "Pacific/Enderbury" , 0x0A0789 }, - { (char*) "Pacific/Fakaofo" , 0x0A0871 }, - { (char*) "Pacific/Fiji" , 0x0A0937 }, - { (char*) "Pacific/Funafuti" , 0x0A0B77 }, - { (char*) "Pacific/Galapagos" , 0x0A0C1B }, - { (char*) "Pacific/Gambier" , 0x0A0D18 }, - { (char*) "Pacific/Guadalcanal" , 0x0A0DC9 }, - { (char*) "Pacific/Guam" , 0x0A0E6D }, - { (char*) "Pacific/Honolulu" , 0x0A1067 }, - { (char*) "Pacific/Johnston" , 0x0A11C2 }, - { (char*) "Pacific/Kanton" , 0x0A1317 }, - { (char*) "Pacific/Kiritimati" , 0x0A140E }, - { (char*) "Pacific/Kosrae" , 0x0A1506 }, - { (char*) "Pacific/Kwajalein" , 0x0A1669 }, - { (char*) "Pacific/Majuro" , 0x0A17AC }, - { (char*) "Pacific/Marquesas" , 0x0A18F8 }, - { (char*) "Pacific/Midway" , 0x0A19B4 }, - { (char*) "Pacific/Nauru" , 0x0A1AA7 }, - { (char*) "Pacific/Niue" , 0x0A1BA1 }, - { (char*) "Pacific/Norfolk" , 0x0A1C6A }, - { (char*) "Pacific/Noumea" , 0x0A1FD8 }, - { (char*) "Pacific/Pago_Pago" , 0x0A2106 }, - { (char*) "Pacific/Palau" , 0x0A21C1 }, - { (char*) "Pacific/Pitcairn" , 0x0A2273 }, - { (char*) "Pacific/Pohnpei" , 0x0A233B }, - { (char*) "Pacific/Ponape" , 0x0A2476 }, - { (char*) "Pacific/Port_Moresby" , 0x0A251A }, - { (char*) "Pacific/Rarotonga" , 0x0A25EA }, - { (char*) "Pacific/Saipan" , 0x0A2843 }, - { (char*) "Pacific/Samoa" , 0x0A2A2F }, - { (char*) "Pacific/Tahiti" , 0x0A2AEA }, - { (char*) "Pacific/Tarawa" , 0x0A2B9C }, - { (char*) "Pacific/Tongatapu" , 0x0A2C4F }, - { (char*) "Pacific/Truk" , 0x0A2DC1 }, - { (char*) "Pacific/Wake" , 0x0A2E79 }, - { (char*) "Pacific/Wallis" , 0x0A2F28 }, - { (char*) "Pacific/Yap" , 0x0A2FCC }, - { (char*) "Poland" , 0x0A3084 }, - { (char*) "Portugal" , 0x0A3AEE }, - { (char*) "PRC" , 0x0A48C1 }, - { (char*) "PST8PDT" , 0x0A4AFE }, - { (char*) "ROC" , 0x0A562E }, - { (char*) "ROK" , 0x0A5933 }, - { (char*) "Singapore" , 0x0A5BA8 }, - { (char*) "Turkey" , 0x0A5D45 }, - { (char*) "UCT" , 0x0A64DE }, - { (char*) "Universal" , 0x0A655C }, - { (char*) "US/Alaska" , 0x0A65DA }, - { (char*) "US/Aleutian" , 0x0A6F29 }, - { (char*) "US/Arizona" , 0x0A7869 }, - { (char*) "US/Central" , 0x0A79DD }, - { (char*) "US/East-Indiana" , 0x0A87F1 }, - { (char*) "US/Eastern" , 0x0A8E8F }, - { (char*) "US/Hawaii" , 0x0A9C7B }, - { (char*) "US/Indiana-Starke" , 0x0A9DD0 }, - { (char*) "US/Michigan" , 0x0AA768 }, - { (char*) "US/Mountain" , 0x0AB02A }, - { (char*) "US/Pacific" , 0x0AB9D2 }, - { (char*) "US/Samoa" , 0x0AC502 }, - { (char*) "UTC" , 0x0AC5BD }, - { (char*) "W-SU" , 0x0AC63B }, - { (char*) "WET" , 0x0ACC46 }, - { (char*) "Zulu" , 0x0ADA19 }, + { (char*) "America/Coyhaique" , 0x011AEB }, + { (char*) "America/Creston" , 0x012351 }, + { (char*) "America/Cuiaba" , 0x01243F }, + { (char*) "America/Curacao" , 0x0129D0 }, + { (char*) "America/Danmarkshavn" , 0x012A96 }, + { (char*) "America/Dawson" , 0x012D76 }, + { (char*) "America/Dawson_Creek" , 0x0133E2 }, + { (char*) "America/Denver" , 0x013828 }, + { (char*) "America/Detroit" , 0x0141E5 }, + { (char*) "America/Dominica" , 0x014AC0 }, + { (char*) "America/Edmonton" , 0x014B60 }, + { (char*) "America/Eirunepe" , 0x0154AA }, + { (char*) "America/El_Salvador" , 0x015747 }, + { (char*) "America/Ensenada" , 0x015833 }, + { (char*) "America/Fort_Nelson" , 0x0161D9 }, + { (char*) "America/Fort_Wayne" , 0x016AB9 }, + { (char*) "America/Fortaleza" , 0x017157 }, + { (char*) "America/Glace_Bay" , 0x017447 }, + { (char*) "America/Godthab" , 0x017CFE }, + { (char*) "America/Goose_Bay" , 0x01846B }, + { (char*) "America/Grand_Turk" , 0x019121 }, + { (char*) "America/Grenada" , 0x019857 }, + { (char*) "America/Guadeloupe" , 0x0198F7 }, + { (char*) "America/Guatemala" , 0x019997 }, + { (char*) "America/Guayaquil" , 0x019ABB }, + { (char*) "America/Guyana" , 0x019BC1 }, + { (char*) "America/Halifax" , 0x019CC5 }, + { (char*) "America/Havana" , 0x01AA4F }, + { (char*) "America/Hermosillo" , 0x01B3CB }, + { (char*) "America/Indiana/Indianapolis" , 0x01B561 }, + { (char*) "America/Indiana/Knox" , 0x01BC18 }, + { (char*) "America/Indiana/Marengo" , 0x01C5C5 }, + { (char*) "America/Indiana/Petersburg" , 0x01CCB2 }, + { (char*) "America/Indiana/Tell_City" , 0x01D451 }, + { (char*) "America/Indiana/Vevay" , 0x01DB15 }, + { (char*) "America/Indiana/Vincennes" , 0x01E0D1 }, + { (char*) "America/Indiana/Winamac" , 0x01E7A7 }, + { (char*) "America/Indianapolis" , 0x01EECB }, + { (char*) "America/Inuvik" , 0x01F569 }, + { (char*) "America/Iqaluit" , 0x01FDA3 }, + { (char*) "America/Jamaica" , 0x020662 }, + { (char*) "America/Jujuy" , 0x020850 }, + { (char*) "America/Juneau" , 0x020C66 }, + { (char*) "America/Kentucky/Louisville" , 0x0215B7 }, + { (char*) "America/Kentucky/Monticello" , 0x0220C5 }, + { (char*) "America/Knox_IN" , 0x022A25 }, + { (char*) "America/Kralendijk" , 0x0233BD }, + { (char*) "America/La_Paz" , 0x0234BF }, + { (char*) "America/Lima" , 0x0235A5 }, + { (char*) "America/Los_Angeles" , 0x023739 }, + { (char*) "America/Louisville" , 0x024270 }, + { (char*) "America/Lower_Princes" , 0x024D60 }, + { (char*) "America/Maceio" , 0x024E62 }, + { (char*) "America/Managua" , 0x025158 }, + { (char*) "America/Manaus" , 0x025312 }, + { (char*) "America/Marigot" , 0x02557B }, + { (char*) "America/Martinique" , 0x02567D }, + { (char*) "America/Matamoros" , 0x025771 }, + { (char*) "America/Mazatlan" , 0x025D33 }, + { (char*) "America/Mendoza" , 0x026195 }, + { (char*) "America/Menominee" , 0x0265C7 }, + { (char*) "America/Merida" , 0x026ED4 }, + { (char*) "America/Metlakatla" , 0x0272DD }, + { (char*) "America/Mexico_City" , 0x02788F }, + { (char*) "America/Miquelon" , 0x027D6F }, + { (char*) "America/Moncton" , 0x0283EF }, + { (char*) "America/Monterrey" , 0x029065 }, + { (char*) "America/Montevideo" , 0x029501 }, + { (char*) "America/Montreal" , 0x029AE5 }, + { (char*) "America/Montserrat" , 0x02A897 }, + { (char*) "America/Nassau" , 0x02A937 }, + { (char*) "America/New_York" , 0x02B297 }, + { (char*) "America/Nipigon" , 0x02C097 }, + { (char*) "America/Nome" , 0x02CE49 }, + { (char*) "America/Noronha" , 0x02D7A1 }, + { (char*) "America/North_Dakota/Beulah" , 0x02DA7B }, + { (char*) "America/North_Dakota/Center" , 0x02E3F8 }, + { (char*) "America/North_Dakota/New_Salem" , 0x02ED75 }, + { (char*) "America/Nuuk" , 0x02F6F8 }, + { (char*) "America/Ojinaga" , 0x02FE76 }, + { (char*) "America/Panama" , 0x030492 }, + { (char*) "America/Pangnirtung" , 0x030554 }, + { (char*) "America/Paramaribo" , 0x030DFA }, + { (char*) "America/Phoenix" , 0x030EFE }, + { (char*) "America/Port-au-Prince" , 0x03108A }, + { (char*) "America/Port_of_Spain" , 0x031630 }, + { (char*) "America/Porto_Acre" , 0x0316D0 }, + { (char*) "America/Porto_Velho" , 0x031942 }, + { (char*) "America/Puerto_Rico" , 0x031B88 }, + { (char*) "America/Punta_Arenas" , 0x031C8A }, + { (char*) "America/Rainy_River" , 0x032415 }, + { (char*) "America/Rankin_Inlet" , 0x032F55 }, + { (char*) "America/Recife" , 0x033789 }, + { (char*) "America/Regina" , 0x033A5D }, + { (char*) "America/Resolute" , 0x033E52 }, + { (char*) "America/Rio_Branco" , 0x034687 }, + { (char*) "America/Rosario" , 0x0348FD }, + { (char*) "America/Santa_Isabel" , 0x034D2F }, + { (char*) "America/Santarem" , 0x0356D5 }, + { (char*) "America/Santiago" , 0x035938 }, + { (char*) "America/Santo_Domingo" , 0x036324 }, + { (char*) "America/Sao_Paulo" , 0x0364FA }, + { (char*) "America/Scoresbysund" , 0x036AD2 }, + { (char*) "America/Shiprock" , 0x03728A }, + { (char*) "America/Sitka" , 0x037C32 }, + { (char*) "America/St_Barthelemy" , 0x03856A }, + { (char*) "America/St_Johns" , 0x03866C }, + { (char*) "America/St_Kitts" , 0x0394DA }, + { (char*) "America/St_Lucia" , 0x03957A }, + { (char*) "America/St_Thomas" , 0x03963C }, + { (char*) "America/St_Vincent" , 0x0396DC }, + { (char*) "America/Swift_Current" , 0x03979E }, + { (char*) "America/Tegucigalpa" , 0x0399EC }, + { (char*) "America/Thule" , 0x039AF4 }, + { (char*) "America/Thunder_Bay" , 0x03A0EC }, + { (char*) "America/Tijuana" , 0x03AE9E }, + { (char*) "America/Toronto" , 0x03B853 }, + { (char*) "America/Tortola" , 0x03C623 }, + { (char*) "America/Vancouver" , 0x03C6C3 }, + { (char*) "America/Virgin" , 0x03D234 }, + { (char*) "America/Whitehorse" , 0x03D336 }, + { (char*) "America/Winnipeg" , 0x03D9A2 }, + { (char*) "America/Yakutat" , 0x03E4FF }, + { (char*) "America/Yellowknife" , 0x03EE1C }, + { (char*) "Antarctica/Casey" , 0x03F744 }, + { (char*) "Antarctica/Davis" , 0x03F8FC }, + { (char*) "Antarctica/DumontDUrville" , 0x03FA28 }, + { (char*) "Antarctica/Macquarie" , 0x03FAF8 }, + { (char*) "Antarctica/Mawson" , 0x0403E8 }, + { (char*) "Antarctica/McMurdo" , 0x0404B3 }, + { (char*) "Antarctica/Palmer" , 0x040CAE }, + { (char*) "Antarctica/Rothera" , 0x04123C }, + { (char*) "Antarctica/South_Pole" , 0x0412E5 }, + { (char*) "Antarctica/Syowa" , 0x041C76 }, + { (char*) "Antarctica/Troll" , 0x041D1E }, + { (char*) "Antarctica/Vostok" , 0x0421AB }, + { (char*) "Arctic/Longyearbyen" , 0x042292 }, + { (char*) "Asia/Aden" , 0x042B98 }, + { (char*) "Asia/Almaty" , 0x042C3B }, + { (char*) "Asia/Amman" , 0x043030 }, + { (char*) "Asia/Anadyr" , 0x0435D5 }, + { (char*) "Asia/Aqtau" , 0x043A8A }, + { (char*) "Asia/Aqtobe" , 0x043E74 }, + { (char*) "Asia/Ashgabat" , 0x044272 }, + { (char*) "Asia/Ashkhabad" , 0x0444DB }, + { (char*) "Asia/Atyrau" , 0x044744 }, + { (char*) "Asia/Baghdad" , 0x044B36 }, + { (char*) "Asia/Bahrain" , 0x044F0B }, + { (char*) "Asia/Baku" , 0x044FF6 }, + { (char*) "Asia/Bangkok" , 0x0454BF }, + { (char*) "Asia/Barnaul" , 0x045584 }, + { (char*) "Asia/Beirut" , 0x045A55 }, + { (char*) "Asia/Bishkek" , 0x0462CB }, + { (char*) "Asia/Brunei" , 0x0466A0 }, + { (char*) "Asia/Calcutta" , 0x046769 }, + { (char*) "Asia/Chita" , 0x046892 }, + { (char*) "Asia/Choibalsan" , 0x046D69 }, + { (char*) "Asia/Chongqing" , 0x0470E2 }, + { (char*) "Asia/Chungking" , 0x04731F }, + { (char*) "Asia/Colombo" , 0x04755C }, + { (char*) "Asia/Dacca" , 0x0476CE }, + { (char*) "Asia/Damascus" , 0x04781D }, + { (char*) "Asia/Dhaka" , 0x047F7A }, + { (char*) "Asia/Dili" , 0x0480C9 }, + { (char*) "Asia/Dubai" , 0x0481D6 }, + { (char*) "Asia/Dushanbe" , 0x048279 }, + { (char*) "Asia/Famagusta" , 0x0484C6 }, + { (char*) "Asia/Gaza" , 0x048CCD }, + { (char*) "Asia/Harbin" , 0x049BE7 }, + { (char*) "Asia/Hebron" , 0x049E24 }, + { (char*) "Asia/Ho_Chi_Minh" , 0x04AD59 }, + { (char*) "Asia/Hong_Kong" , 0x04AEB6 }, + { (char*) "Asia/Hovd" , 0x04B393 }, + { (char*) "Asia/Irkutsk" , 0x04B722 }, + { (char*) "Asia/Istanbul" , 0x04BC15 }, + { (char*) "Asia/Jakarta" , 0x04C3AE }, + { (char*) "Asia/Jayapura" , 0x04C546 }, + { (char*) "Asia/Jerusalem" , 0x04C665 }, + { (char*) "Asia/Kabul" , 0x04CFC5 }, + { (char*) "Asia/Kamchatka" , 0x04D093 }, + { (char*) "Asia/Karachi" , 0x04D531 }, + { (char*) "Asia/Kashgar" , 0x04D6B8 }, + { (char*) "Asia/Kathmandu" , 0x04D75B }, + { (char*) "Asia/Katmandu" , 0x04D82D }, + { (char*) "Asia/Khandyga" , 0x04D8FF }, + { (char*) "Asia/Kolkata" , 0x04DE12 }, + { (char*) "Asia/Krasnoyarsk" , 0x04DF3B }, + { (char*) "Asia/Kuala_Lumpur" , 0x04E409 }, + { (char*) "Asia/Kuching" , 0x04E5BA }, + { (char*) "Asia/Kuwait" , 0x04E7A9 }, + { (char*) "Asia/Macao" , 0x04E84C }, + { (char*) "Asia/Macau" , 0x04ED23 }, + { (char*) "Asia/Magadan" , 0x04F1FA }, + { (char*) "Asia/Makassar" , 0x04F6CE }, + { (char*) "Asia/Manila" , 0x04F821 }, + { (char*) "Asia/Muscat" , 0x04F9D3 }, + { (char*) "Asia/Nicosia" , 0x04FA76 }, + { (char*) "Asia/Novokuznetsk" , 0x050262 }, + { (char*) "Asia/Novosibirsk" , 0x0506FE }, + { (char*) "Asia/Omsk" , 0x050BD5 }, + { (char*) "Asia/Oral" , 0x051097 }, + { (char*) "Asia/Phnom_Penh" , 0x051491 }, + { (char*) "Asia/Pontianak" , 0x0515B6 }, + { (char*) "Asia/Pyongyang" , 0x051739 }, + { (char*) "Asia/Qatar" , 0x051832 }, + { (char*) "Asia/Qostanay" , 0x0518F7 }, + { (char*) "Asia/Qyzylorda" , 0x051D1E }, + { (char*) "Asia/Rangoon" , 0x05213A }, + { (char*) "Asia/Riyadh" , 0x052244 }, + { (char*) "Asia/Saigon" , 0x0522E7 }, + { (char*) "Asia/Sakhalin" , 0x052444 }, + { (char*) "Asia/Samarkand" , 0x05290C }, + { (char*) "Asia/Seoul" , 0x052B5C }, + { (char*) "Asia/Shanghai" , 0x052DD1 }, + { (char*) "Asia/Singapore" , 0x05301A }, + { (char*) "Asia/Srednekolymsk" , 0x0531B7 }, + { (char*) "Asia/Taipei" , 0x05368B }, + { (char*) "Asia/Tashkent" , 0x053990 }, + { (char*) "Asia/Tbilisi" , 0x053BEE }, + { (char*) "Asia/Tehran" , 0x053FF7 }, + { (char*) "Asia/Tel_Aviv" , 0x0544E3 }, + { (char*) "Asia/Thimbu" , 0x054E43 }, + { (char*) "Asia/Thimphu" , 0x054F0C }, + { (char*) "Asia/Tokyo" , 0x054FD5 }, + { (char*) "Asia/Tomsk" , 0x055116 }, + { (char*) "Asia/Ujung_Pandang" , 0x0555E7 }, + { (char*) "Asia/Ulaanbaatar" , 0x0556F1 }, + { (char*) "Asia/Ulan_Bator" , 0x055A7A }, + { (char*) "Asia/Urumqi" , 0x055DF3 }, + { (char*) "Asia/Ust-Nera" , 0x055EA3 }, + { (char*) "Asia/Vientiane" , 0x056399 }, + { (char*) "Asia/Vladivostok" , 0x0564DA }, + { (char*) "Asia/Yakutsk" , 0x0569A3 }, + { (char*) "Asia/Yangon" , 0x056E6B }, + { (char*) "Asia/Yekaterinburg" , 0x056F75 }, + { (char*) "Asia/Yerevan" , 0x05745C }, + { (char*) "Atlantic/Azores" , 0x0578D9 }, + { (char*) "Atlantic/Bermuda" , 0x05865D }, + { (char*) "Atlantic/Canary" , 0x058FC5 }, + { (char*) "Atlantic/Cape_Verde" , 0x059748 }, + { (char*) "Atlantic/Faeroe" , 0x059854 }, + { (char*) "Atlantic/Faroe" , 0x059F77 }, + { (char*) "Atlantic/Jan_Mayen" , 0x05A69A }, + { (char*) "Atlantic/Madeira" , 0x05AFA0 }, + { (char*) "Atlantic/Reykjavik" , 0x05BCEC }, + { (char*) "Atlantic/South_Georgia" , 0x05C182 }, + { (char*) "Atlantic/St_Helena" , 0x05C224 }, + { (char*) "Atlantic/Stanley" , 0x05C2E6 }, + { (char*) "Australia/ACT" , 0x05C7A2 }, + { (char*) "Australia/Adelaide" , 0x05D03C }, + { (char*) "Australia/Brisbane" , 0x05D8F7 }, + { (char*) "Australia/Broken_Hill" , 0x05DABD }, + { (char*) "Australia/Canberra" , 0x05E39A }, + { (char*) "Australia/Currie" , 0x05EC34 }, + { (char*) "Australia/Darwin" , 0x05F576 }, + { (char*) "Australia/Eucla" , 0x05F6D9 }, + { (char*) "Australia/Hobart" , 0x05F8C6 }, + { (char*) "Australia/LHI" , 0x060210 }, + { (char*) "Australia/Lindeman" , 0x060952 }, + { (char*) "Australia/Lord_Howe" , 0x060B58 }, + { (char*) "Australia/Melbourne" , 0x0612AA }, + { (char*) "Australia/North" , 0x061B4C }, + { (char*) "Australia/NSW" , 0x061C9D }, + { (char*) "Australia/Perth" , 0x062537 }, + { (char*) "Australia/Queensland" , 0x06271F }, + { (char*) "Australia/South" , 0x0628CE }, + { (char*) "Australia/Sydney" , 0x06317A }, + { (char*) "Australia/Tasmania" , 0x063A30 }, + { (char*) "Australia/Victoria" , 0x064372 }, + { (char*) "Australia/West" , 0x064C0C }, + { (char*) "Australia/Yancowinna" , 0x064DD6 }, + { (char*) "Brazil/Acre" , 0x065697 }, + { (char*) "Brazil/DeNoronha" , 0x065909 }, + { (char*) "Brazil/East" , 0x065BD3 }, + { (char*) "Brazil/West" , 0x066175 }, + { (char*) "Canada/Atlantic" , 0x0663CF }, + { (char*) "Canada/Central" , 0x06713B }, + { (char*) "Canada/Eastern" , 0x067C7B }, + { (char*) "Canada/Mountain" , 0x068A2D }, + { (char*) "Canada/Newfoundland" , 0x069355 }, + { (char*) "Canada/Pacific" , 0x06A1A8 }, + { (char*) "Canada/Saskatchewan" , 0x06AD00 }, + { (char*) "Canada/Yukon" , 0x06B0E0 }, + { (char*) "CET" , 0x06B73A }, + { (char*) "Chile/Continental" , 0x06C2BB }, + { (char*) "Chile/EasterIsland" , 0x06CC9A }, + { (char*) "CST6CDT" , 0x06D551 }, + { (char*) "Cuba" , 0x06E365 }, + { (char*) "EET" , 0x06ECE1 }, + { (char*) "Egypt" , 0x06F5C3 }, + { (char*) "Eire" , 0x06FF2E }, + { (char*) "EST" , 0x070CDE }, + { (char*) "EST5EDT" , 0x070DA0 }, + { (char*) "Etc/GMT" , 0x071B8C }, + { (char*) "Etc/GMT+0" , 0x071C0A }, + { (char*) "Etc/GMT+1" , 0x071C88 }, + { (char*) "Etc/GMT+10" , 0x071D08 }, + { (char*) "Etc/GMT+11" , 0x071D89 }, + { (char*) "Etc/GMT+12" , 0x071E0A }, + { (char*) "Etc/GMT+2" , 0x071E8B }, + { (char*) "Etc/GMT+3" , 0x071F0B }, + { (char*) "Etc/GMT+4" , 0x071F8B }, + { (char*) "Etc/GMT+5" , 0x07200B }, + { (char*) "Etc/GMT+6" , 0x07208B }, + { (char*) "Etc/GMT+7" , 0x07210B }, + { (char*) "Etc/GMT+8" , 0x07218B }, + { (char*) "Etc/GMT+9" , 0x07220B }, + { (char*) "Etc/GMT-0" , 0x07228B }, + { (char*) "Etc/GMT-1" , 0x072309 }, + { (char*) "Etc/GMT-10" , 0x07238A }, + { (char*) "Etc/GMT-11" , 0x07240C }, + { (char*) "Etc/GMT-12" , 0x07248E }, + { (char*) "Etc/GMT-13" , 0x072510 }, + { (char*) "Etc/GMT-14" , 0x072592 }, + { (char*) "Etc/GMT-2" , 0x072614 }, + { (char*) "Etc/GMT-3" , 0x072695 }, + { (char*) "Etc/GMT-4" , 0x072716 }, + { (char*) "Etc/GMT-5" , 0x072797 }, + { (char*) "Etc/GMT-6" , 0x072818 }, + { (char*) "Etc/GMT-7" , 0x072899 }, + { (char*) "Etc/GMT-8" , 0x07291A }, + { (char*) "Etc/GMT-9" , 0x07299B }, + { (char*) "Etc/GMT0" , 0x072A1C }, + { (char*) "Etc/Greenwich" , 0x072A9A }, + { (char*) "Etc/UCT" , 0x072B18 }, + { (char*) "Etc/Universal" , 0x072B96 }, + { (char*) "Etc/UTC" , 0x072C14 }, + { (char*) "Etc/Zulu" , 0x072C92 }, + { (char*) "Europe/Amsterdam" , 0x072D10 }, + { (char*) "Europe/Andorra" , 0x07387A }, + { (char*) "Europe/Astrakhan" , 0x073F54 }, + { (char*) "Europe/Athens" , 0x0743F1 }, + { (char*) "Europe/Belfast" , 0x074CD3 }, + { (char*) "Europe/Belgrade" , 0x075B2F }, + { (char*) "Europe/Berlin" , 0x0762BB }, + { (char*) "Europe/Bratislava" , 0x076BD0 }, + { (char*) "Europe/Brussels" , 0x0774D9 }, + { (char*) "Europe/Bucharest" , 0x07805A }, + { (char*) "Europe/Budapest" , 0x0788EE }, + { (char*) "Europe/Busingen" , 0x07923A }, + { (char*) "Europe/Chisinau" , 0x0799C3 }, + { (char*) "Europe/Copenhagen" , 0x07A325 }, + { (char*) "Europe/Dublin" , 0x07AB8A }, + { (char*) "Europe/Gibraltar" , 0x07B93A }, + { (char*) "Europe/Guernsey" , 0x07C542 }, + { (char*) "Europe/Helsinki" , 0x07D3E2 }, + { (char*) "Europe/Isle_of_Man" , 0x07DB5A }, + { (char*) "Europe/Istanbul" , 0x07E9A6 }, + { (char*) "Europe/Jersey" , 0x07F13F }, + { (char*) "Europe/Kaliningrad" , 0x07FFDF }, + { (char*) "Europe/Kiev" , 0x0805D4 }, + { (char*) "Europe/Kirov" , 0x080E28 }, + { (char*) "Europe/Kyiv" , 0x0812E3 }, + { (char*) "Europe/Lisbon" , 0x081B46 }, + { (char*) "Europe/Ljubljana" , 0x08292C }, + { (char*) "Europe/London" , 0x0830B8 }, + { (char*) "Europe/Luxembourg" , 0x083F14 }, + { (char*) "Europe/Madrid" , 0x084AA2 }, + { (char*) "Europe/Malta" , 0x0854F4 }, + { (char*) "Europe/Mariehamn" , 0x085F3C }, + { (char*) "Europe/Minsk" , 0x0866B4 }, + { (char*) "Europe/Monaco" , 0x086BDB }, + { (char*) "Europe/Moscow" , 0x087767 }, + { (char*) "Europe/Nicosia" , 0x087D86 }, + { (char*) "Europe/Oslo" , 0x088564 }, + { (char*) "Europe/Paris" , 0x088E24 }, + { (char*) "Europe/Podgorica" , 0x0899C2 }, + { (char*) "Europe/Prague" , 0x08A14E }, + { (char*) "Europe/Riga" , 0x08AA57 }, + { (char*) "Europe/Rome" , 0x08B2F9 }, + { (char*) "Europe/Samara" , 0x08BD56 }, + { (char*) "Europe/San_Marino" , 0x08C22C }, + { (char*) "Europe/Sarajevo" , 0x08CC89 }, + { (char*) "Europe/Saratov" , 0x08D415 }, + { (char*) "Europe/Simferopol" , 0x08D8C2 }, + { (char*) "Europe/Skopje" , 0x08DE91 }, + { (char*) "Europe/Sofia" , 0x08E61D }, + { (char*) "Europe/Stockholm" , 0x08EE46 }, + { (char*) "Europe/Tallinn" , 0x08F5C7 }, + { (char*) "Europe/Tirane" , 0x08FE37 }, + { (char*) "Europe/Tiraspol" , 0x090667 }, + { (char*) "Europe/Ulyanovsk" , 0x090FC9 }, + { (char*) "Europe/Uzhgorod" , 0x0914CC }, + { (char*) "Europe/Vaduz" , 0x091D20 }, + { (char*) "Europe/Vatican" , 0x09248C }, + { (char*) "Europe/Vienna" , 0x092EE9 }, + { (char*) "Europe/Vilnius" , 0x09378D }, + { (char*) "Europe/Volgograd" , 0x09400B }, + { (char*) "Europe/Warsaw" , 0x0944D2 }, + { (char*) "Europe/Zagreb" , 0x094F3C }, + { (char*) "Europe/Zaporozhye" , 0x0956C8 }, + { (char*) "Europe/Zurich" , 0x095F1C }, + { (char*) "Factory" , 0x09669D }, + { (char*) "GB" , 0x09671D }, + { (char*) "GB-Eire" , 0x097579 }, + { (char*) "GMT" , 0x0983D5 }, + { (char*) "GMT+0" , 0x098453 }, + { (char*) "GMT-0" , 0x0984D1 }, + { (char*) "GMT0" , 0x09854F }, + { (char*) "Greenwich" , 0x0985CD }, + { (char*) "Hongkong" , 0x09864B }, + { (char*) "HST" , 0x098B28 }, + { (char*) "Iceland" , 0x098C7D }, + { (char*) "Indian/Antananarivo" , 0x098D1D }, + { (char*) "Indian/Chagos" , 0x098E04 }, + { (char*) "Indian/Christmas" , 0x098EC9 }, + { (char*) "Indian/Cocos" , 0x098F6C }, + { (char*) "Indian/Comoro" , 0x099018 }, + { (char*) "Indian/Kerguelen" , 0x0990B9 }, + { (char*) "Indian/Mahe" , 0x09915C }, + { (char*) "Indian/Maldives" , 0x0991FF }, + { (char*) "Indian/Mauritius" , 0x0992C4 }, + { (char*) "Indian/Mayotte" , 0x0993B3 }, + { (char*) "Indian/Reunion" , 0x099454 }, + { (char*) "Iran" , 0x0994F7 }, + { (char*) "Israel" , 0x0999E3 }, + { (char*) "Jamaica" , 0x09A343 }, + { (char*) "Japan" , 0x09A531 }, + { (char*) "Kwajalein" , 0x09A672 }, + { (char*) "Libya" , 0x09A7AC }, + { (char*) "MET" , 0x09AA29 }, + { (char*) "Mexico/BajaNorte" , 0x09B5AA }, + { (char*) "Mexico/BajaSur" , 0x09BF50 }, + { (char*) "Mexico/General" , 0x09C380 }, + { (char*) "MST" , 0x09C852 }, + { (char*) "MST7MDT" , 0x09C9C6 }, + { (char*) "Navajo" , 0x09D36E }, + { (char*) "NZ" , 0x09DD16 }, + { (char*) "NZ-CHAT" , 0x09E6A7 }, + { (char*) "Pacific/Apia" , 0x09EEB9 }, + { (char*) "Pacific/Auckland" , 0x09F11B }, + { (char*) "Pacific/Bougainville" , 0x09FABF }, + { (char*) "Pacific/Chatham" , 0x09FBD5 }, + { (char*) "Pacific/Chuuk" , 0x0A03F6 }, + { (char*) "Pacific/Easter" , 0x0A0510 }, + { (char*) "Pacific/Efate" , 0x0A0DD4 }, + { (char*) "Pacific/Enderbury" , 0x0A0FEC }, + { (char*) "Pacific/Fakaofo" , 0x0A10D4 }, + { (char*) "Pacific/Fiji" , 0x0A119A }, + { (char*) "Pacific/Funafuti" , 0x0A13DA }, + { (char*) "Pacific/Galapagos" , 0x0A147E }, + { (char*) "Pacific/Gambier" , 0x0A157B }, + { (char*) "Pacific/Guadalcanal" , 0x0A162C }, + { (char*) "Pacific/Guam" , 0x0A16D0 }, + { (char*) "Pacific/Honolulu" , 0x0A18CA }, + { (char*) "Pacific/Johnston" , 0x0A1A25 }, + { (char*) "Pacific/Kanton" , 0x0A1B7A }, + { (char*) "Pacific/Kiritimati" , 0x0A1C71 }, + { (char*) "Pacific/Kosrae" , 0x0A1D69 }, + { (char*) "Pacific/Kwajalein" , 0x0A1ECC }, + { (char*) "Pacific/Majuro" , 0x0A200F }, + { (char*) "Pacific/Marquesas" , 0x0A215B }, + { (char*) "Pacific/Midway" , 0x0A2217 }, + { (char*) "Pacific/Nauru" , 0x0A230A }, + { (char*) "Pacific/Niue" , 0x0A2404 }, + { (char*) "Pacific/Norfolk" , 0x0A24CD }, + { (char*) "Pacific/Noumea" , 0x0A283B }, + { (char*) "Pacific/Pago_Pago" , 0x0A2969 }, + { (char*) "Pacific/Palau" , 0x0A2A24 }, + { (char*) "Pacific/Pitcairn" , 0x0A2AD6 }, + { (char*) "Pacific/Pohnpei" , 0x0A2B9E }, + { (char*) "Pacific/Ponape" , 0x0A2CD9 }, + { (char*) "Pacific/Port_Moresby" , 0x0A2D7D }, + { (char*) "Pacific/Rarotonga" , 0x0A2E4D }, + { (char*) "Pacific/Saipan" , 0x0A30A6 }, + { (char*) "Pacific/Samoa" , 0x0A3292 }, + { (char*) "Pacific/Tahiti" , 0x0A334D }, + { (char*) "Pacific/Tarawa" , 0x0A33FF }, + { (char*) "Pacific/Tongatapu" , 0x0A34B2 }, + { (char*) "Pacific/Truk" , 0x0A3624 }, + { (char*) "Pacific/Wake" , 0x0A36DC }, + { (char*) "Pacific/Wallis" , 0x0A378B }, + { (char*) "Pacific/Yap" , 0x0A382F }, + { (char*) "Poland" , 0x0A38E7 }, + { (char*) "Portugal" , 0x0A4351 }, + { (char*) "PRC" , 0x0A5124 }, + { (char*) "PST8PDT" , 0x0A5361 }, + { (char*) "ROC" , 0x0A5E91 }, + { (char*) "ROK" , 0x0A6196 }, + { (char*) "Singapore" , 0x0A640B }, + { (char*) "Turkey" , 0x0A65A8 }, + { (char*) "UCT" , 0x0A6D41 }, + { (char*) "Universal" , 0x0A6DBF }, + { (char*) "US/Alaska" , 0x0A6E3D }, + { (char*) "US/Aleutian" , 0x0A778C }, + { (char*) "US/Arizona" , 0x0A80CC }, + { (char*) "US/Central" , 0x0A8240 }, + { (char*) "US/East-Indiana" , 0x0A9054 }, + { (char*) "US/Eastern" , 0x0A96F2 }, + { (char*) "US/Hawaii" , 0x0AA4DE }, + { (char*) "US/Indiana-Starke" , 0x0AA633 }, + { (char*) "US/Michigan" , 0x0AAFCB }, + { (char*) "US/Mountain" , 0x0AB88D }, + { (char*) "US/Pacific" , 0x0AC235 }, + { (char*) "US/Samoa" , 0x0ACD65 }, + { (char*) "UTC" , 0x0ACE20 }, + { (char*) "W-SU" , 0x0ACE9E }, + { (char*) "WET" , 0x0AD4A9 }, + { (char*) "Zulu" , 0x0AE27C }, }; -const unsigned char timelib_timezone_db_data_builtin[711319] = { +const unsigned char timelib_timezone_db_data_builtin[713466] = { /* Africa/Abidjan */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -29630,6 +29720,143 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36, 0x0A, 0x00, 0x98, 0x7C, 0x75, 0x00, 0x92, 0x5B, 0x72, 0x00, 0x00, 0x00, 0x00, +/* America/Coyhaique */ +0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00, +0x8F, 0x30, 0x47, 0x45, 0x9B, 0x5C, 0xE5, 0x50, 0x9F, 0x7C, 0xE2, 0xC5, 0xA1, 0x00, 0x71, 0xC0, +0xB0, 0x5E, 0x77, 0xC5, 0xB1, 0x77, 0x3D, 0x40, 0xB2, 0x41, 0x00, 0xD0, 0xB3, 0x58, 0x70, 0xC0, +0xB4, 0x22, 0x34, 0x50, 0xB5, 0x39, 0xA4, 0x40, 0xB6, 0x03, 0x67, 0xD0, 0xB7, 0x1A, 0xD7, 0xC0, +0xB7, 0xE4, 0x9B, 0x50, 0xB8, 0xFD, 0x5C, 0xC0, 0xB9, 0xC7, 0x20, 0x50, 0xCC, 0x1C, 0x6E, 0x40, +0xCC, 0x6C, 0xE7, 0xD0, 0xD4, 0x17, 0xE3, 0x40, 0xD5, 0x33, 0x55, 0xC0, 0xD5, 0x76, 0x92, 0x40, +0xFD, 0xD1, 0x3C, 0x40, 0xFE, 0x92, 0xFA, 0xB0, 0xFF, 0xCC, 0xCD, 0xC0, 0x00, 0x72, 0xDC, 0xB0, +0x01, 0x75, 0x50, 0xC0, 0x02, 0x40, 0x49, 0xB0, 0x03, 0x55, 0x32, 0xC0, 0x04, 0x20, 0x2B, 0xB0, +0x05, 0x3E, 0x4F, 0x40, 0x06, 0x00, 0x0D, 0xB0, 0x07, 0x0B, 0xBC, 0x40, 0x07, 0xDF, 0xEF, 0xB0, +0x08, 0xFE, 0x13, 0x40, 0x09, 0xBF, 0xD1, 0xB0, 0x0A, 0xDD, 0xF5, 0x40, 0x0B, 0xA8, 0xEE, 0x30, +0x0C, 0xBD, 0xD7, 0x40, 0x0D, 0x88, 0xD0, 0x30, 0x0E, 0x9D, 0xB9, 0x40, 0x0F, 0x68, 0xB2, 0x30, +0x10, 0x86, 0xD5, 0xC0, 0x11, 0x48, 0x94, 0x30, 0x12, 0x66, 0xB7, 0xC0, 0x13, 0x28, 0x76, 0x30, +0x14, 0x46, 0x99, 0xC0, 0x15, 0x11, 0x92, 0xB0, 0x16, 0x26, 0x7B, 0xC0, 0x16, 0xF1, 0x74, 0xB0, +0x18, 0x06, 0x5D, 0xC0, 0x18, 0xD1, 0x56, 0xB0, 0x19, 0xE6, 0x3F, 0xC0, 0x1A, 0xB1, 0x38, 0xB0, +0x1B, 0xCF, 0x5C, 0x40, 0x1C, 0x91, 0x1A, 0xB0, 0x1D, 0xAF, 0x3E, 0x40, 0x1E, 0x70, 0xFC, 0xB0, +0x1F, 0x8F, 0x20, 0x40, 0x20, 0x7F, 0x03, 0x30, 0x21, 0x6F, 0x02, 0x40, 0x22, 0x39, 0xFB, 0x30, +0x23, 0x4E, 0xE4, 0x40, 0x24, 0x19, 0xDD, 0x30, 0x25, 0x38, 0x00, 0xC0, 0x25, 0xF9, 0xBF, 0x30, +0x26, 0xF2, 0xF8, 0xC0, 0x27, 0xD9, 0xA1, 0x30, 0x28, 0xF7, 0xC4, 0xC0, 0x29, 0xC2, 0xBD, 0xB0, +0x2A, 0xD7, 0xA6, 0xC0, 0x2B, 0xA2, 0x9F, 0xB0, 0x2C, 0xB7, 0x88, 0xC0, 0x2D, 0x82, 0x81, 0xB0, +0x2E, 0x97, 0x6A, 0xC0, 0x2F, 0x62, 0x63, 0xB0, 0x30, 0x80, 0x87, 0x40, 0x31, 0x42, 0x45, 0xB0, +0x32, 0x60, 0x69, 0x40, 0x33, 0x3D, 0xD7, 0x30, 0x34, 0x40, 0x4B, 0x40, 0x35, 0x0B, 0x44, 0x30, +0x36, 0x0D, 0xB8, 0x40, 0x37, 0x06, 0xD5, 0xB0, 0x38, 0x00, 0x0F, 0x40, 0x38, 0xCB, 0x08, 0x30, +0x39, 0xE9, 0x2B, 0xC0, 0x3A, 0xAA, 0xEA, 0x30, 0x3B, 0xC9, 0x0D, 0xC0, 0x3C, 0x8A, 0xCC, 0x30, +0x3D, 0xA8, 0xEF, 0xC0, 0x3E, 0x6A, 0xAE, 0x30, 0x3F, 0x88, 0xD1, 0xC0, 0x40, 0x53, 0xCA, 0xB0, +0x41, 0x68, 0xB3, 0xC0, 0x42, 0x33, 0xAC, 0xB0, 0x43, 0x48, 0x95, 0xC0, 0x44, 0x13, 0x8E, 0xB0, +0x45, 0x31, 0xB2, 0x40, 0x45, 0xF3, 0x70, 0xB0, 0x47, 0x11, 0x94, 0x40, 0x47, 0xEF, 0x02, 0x30, +0x48, 0xF1, 0x76, 0x40, 0x49, 0xBC, 0x6F, 0x30, 0x4A, 0xD1, 0x58, 0x40, 0x4B, 0xB8, 0x00, 0xB0, +0x4C, 0xB1, 0x3A, 0x40, 0x4D, 0xC6, 0x07, 0x30, 0x4E, 0x50, 0x82, 0xC0, 0x4F, 0x9C, 0xAE, 0xB0, +0x50, 0x42, 0xD9, 0xC0, 0x51, 0x7C, 0x90, 0xB0, 0x52, 0x2B, 0xF6, 0x40, 0x53, 0x5C, 0x72, 0xB0, +0x54, 0x0B, 0xD8, 0x40, 0x57, 0x37, 0xE6, 0x30, 0x57, 0xAF, 0xEC, 0xC0, 0x59, 0x17, 0xC8, 0x30, +0x59, 0x8F, 0xCE, 0xC0, 0x5A, 0xF7, 0xAA, 0x30, 0x5B, 0x6F, 0xB0, 0xC0, 0x5C, 0xA9, 0x67, 0xB0, +0x5D, 0x74, 0x7C, 0xC0, 0x5E, 0x89, 0x49, 0xB0, 0x5F, 0x54, 0x5E, 0xC0, 0x60, 0x69, 0x2B, 0xB0, +0x61, 0x34, 0x40, 0xC0, 0x62, 0x49, 0x0D, 0xB0, 0x63, 0x1D, 0x5D, 0x40, 0x64, 0x28, 0xEF, 0xB0, +0x64, 0xF4, 0x04, 0xC0, 0x66, 0x12, 0x0C, 0x30, 0x66, 0xDD, 0x21, 0x40, 0x67, 0xDB, 0x84, 0xB0, +0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x03, +0x02, 0x03, 0x04, 0x02, 0x03, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x07, 0xFF, 0xFF, 0xBC, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xBD, 0xBB, 0x00, +0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, +0xC0, 0x01, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0C, 0xFF, +0xFF, 0xD5, 0xD0, 0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x35, +0x00, 0x2D, 0x30, 0x34, 0x00, 0x2D, 0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0x69, 0x87, 0x1F, 0x10, 0xFF, 0xFF, 0xFF, +0xFF, 0x8F, 0x30, 0x47, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x5C, 0xE5, 0x50, 0xFF, 0xFF, 0xFF, +0xFF, 0x9F, 0x7C, 0xE2, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF, 0xA1, 0x00, 0x71, 0xC0, 0xFF, 0xFF, 0xFF, +0xFF, 0xB0, 0x5E, 0x77, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1, 0x77, 0x3D, 0x40, 0xFF, 0xFF, 0xFF, +0xFF, 0xB2, 0x41, 0x00, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x58, 0x70, 0xC0, 0xFF, 0xFF, 0xFF, +0xFF, 0xB4, 0x22, 0x34, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0x39, 0xA4, 0x40, 0xFF, 0xFF, 0xFF, +0xFF, 0xB6, 0x03, 0x67, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0x1A, 0xD7, 0xC0, 0xFF, 0xFF, 0xFF, +0xFF, 0xB7, 0xE4, 0x9B, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0xFD, 0x5C, 0xC0, 0xFF, 0xFF, 0xFF, +0xFF, 0xB9, 0xC7, 0x20, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x1C, 0x6E, 0x40, 0xFF, 0xFF, 0xFF, +0xFF, 0xCC, 0x6C, 0xE7, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x17, 0xE3, 0x40, 0xFF, 0xFF, 0xFF, +0xFF, 0xD5, 0x33, 0x55, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x76, 0x92, 0x40, 0xFF, 0xFF, 0xFF, +0xFF, 0xFD, 0xD1, 0x3C, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x92, 0xFA, 0xB0, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xCC, 0xCD, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xDC, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x01, 0x75, 0x50, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x49, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x03, 0x55, 0x32, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x2B, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x05, 0x3E, 0x4F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0D, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x07, 0x0B, 0xBC, 0x40, 0x00, 0x00, 0x00, 0x00, 0x07, 0xDF, 0xEF, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x08, 0xFE, 0x13, 0x40, 0x00, 0x00, 0x00, 0x00, 0x09, 0xBF, 0xD1, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x0A, 0xDD, 0xF5, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xA8, 0xEE, 0x30, 0x00, 0x00, 0x00, +0x00, 0x0C, 0xBD, 0xD7, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x88, 0xD0, 0x30, 0x00, 0x00, 0x00, +0x00, 0x0E, 0x9D, 0xB9, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x68, 0xB2, 0x30, 0x00, 0x00, 0x00, +0x00, 0x10, 0x86, 0xD5, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x11, 0x48, 0x94, 0x30, 0x00, 0x00, 0x00, +0x00, 0x12, 0x66, 0xB7, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x13, 0x28, 0x76, 0x30, 0x00, 0x00, 0x00, +0x00, 0x14, 0x46, 0x99, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x92, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x16, 0x26, 0x7B, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x16, 0xF1, 0x74, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x18, 0x06, 0x5D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x18, 0xD1, 0x56, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x19, 0xE6, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xB1, 0x38, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x1B, 0xCF, 0x5C, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x91, 0x1A, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x1D, 0xAF, 0x3E, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x70, 0xFC, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x1F, 0x8F, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7F, 0x03, 0x30, 0x00, 0x00, 0x00, +0x00, 0x21, 0x6F, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x22, 0x39, 0xFB, 0x30, 0x00, 0x00, 0x00, +0x00, 0x23, 0x4E, 0xE4, 0x40, 0x00, 0x00, 0x00, 0x00, 0x24, 0x19, 0xDD, 0x30, 0x00, 0x00, 0x00, +0x00, 0x25, 0x38, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x25, 0xF9, 0xBF, 0x30, 0x00, 0x00, 0x00, +0x00, 0x26, 0xF2, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x27, 0xD9, 0xA1, 0x30, 0x00, 0x00, 0x00, +0x00, 0x28, 0xF7, 0xC4, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x29, 0xC2, 0xBD, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x2A, 0xD7, 0xA6, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xA2, 0x9F, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x2C, 0xB7, 0x88, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x82, 0x81, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x2E, 0x97, 0x6A, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x62, 0x63, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x30, 0x80, 0x87, 0x40, 0x00, 0x00, 0x00, 0x00, 0x31, 0x42, 0x45, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x32, 0x60, 0x69, 0x40, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3D, 0xD7, 0x30, 0x00, 0x00, 0x00, +0x00, 0x34, 0x40, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x35, 0x0B, 0x44, 0x30, 0x00, 0x00, 0x00, +0x00, 0x36, 0x0D, 0xB8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x37, 0x06, 0xD5, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x38, 0x00, 0x0F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x38, 0xCB, 0x08, 0x30, 0x00, 0x00, 0x00, +0x00, 0x39, 0xE9, 0x2B, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xAA, 0xEA, 0x30, 0x00, 0x00, 0x00, +0x00, 0x3B, 0xC9, 0x0D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x8A, 0xCC, 0x30, 0x00, 0x00, 0x00, +0x00, 0x3D, 0xA8, 0xEF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x6A, 0xAE, 0x30, 0x00, 0x00, 0x00, +0x00, 0x3F, 0x88, 0xD1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xCA, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x41, 0x68, 0xB3, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x42, 0x33, 0xAC, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x43, 0x48, 0x95, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x44, 0x13, 0x8E, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x45, 0x31, 0xB2, 0x40, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0x70, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x47, 0x11, 0x94, 0x40, 0x00, 0x00, 0x00, 0x00, 0x47, 0xEF, 0x02, 0x30, 0x00, 0x00, 0x00, +0x00, 0x48, 0xF1, 0x76, 0x40, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBC, 0x6F, 0x30, 0x00, 0x00, 0x00, +0x00, 0x4A, 0xD1, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xB8, 0x00, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x4C, 0xB1, 0x3A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xC6, 0x07, 0x30, 0x00, 0x00, 0x00, +0x00, 0x4E, 0x50, 0x82, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9C, 0xAE, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x50, 0x42, 0xD9, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x51, 0x7C, 0x90, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x52, 0x2B, 0xF6, 0x40, 0x00, 0x00, 0x00, 0x00, 0x53, 0x5C, 0x72, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x54, 0x0B, 0xD8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x57, 0x37, 0xE6, 0x30, 0x00, 0x00, 0x00, +0x00, 0x57, 0xAF, 0xEC, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x59, 0x17, 0xC8, 0x30, 0x00, 0x00, 0x00, +0x00, 0x59, 0x8F, 0xCE, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xF7, 0xAA, 0x30, 0x00, 0x00, 0x00, +0x00, 0x5B, 0x6F, 0xB0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xA9, 0x67, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x5D, 0x74, 0x7C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x89, 0x49, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x5F, 0x54, 0x5E, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x69, 0x2B, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x61, 0x34, 0x40, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x62, 0x49, 0x0D, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x63, 0x1D, 0x5D, 0x40, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0xEF, 0xB0, 0x00, 0x00, 0x00, +0x00, 0x64, 0xF4, 0x04, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x66, 0x12, 0x0C, 0x30, 0x00, 0x00, 0x00, +0x00, 0x66, 0xDD, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x67, 0xDB, 0x84, 0xB0, 0x01, 0x02, 0x01, +0x03, 0x01, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x03, 0x02, 0x03, 0x04, +0x02, 0x03, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, +0x05, 0x07, 0xFF, 0xFF, 0xBC, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xBD, 0xBB, 0x00, 0x04, 0xFF, 0xFF, +0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, +0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, +0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x35, 0x00, 0x2D, 0x30, +0x34, 0x00, 0x2D, 0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0A, 0x3C, 0x2D, 0x30, 0x33, 0x3E, 0x33, 0x0A, 0x00, 0x43, +0xCC, 0xC5, 0x00, 0xA4, 0xB1, 0x75, 0x00, 0x00, 0x00, 0x0C, 0x41, 0x79, 0x73, 0x65, 0x6E, 0x20, +0x52, 0x65, 0x67, 0x69, 0x6F, 0x6E, + /* America/Creston */ 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -38062,8 +38289,8 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { 0x00, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x35, 0x00, 0x2D, 0x30, 0x34, 0x00, 0x2D, 0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0A, 0x3C, 0x2D, 0x30, 0x33, 0x3E, 0x33, 0x0A, 0x00, 0x38, -0x3A, 0x88, 0x00, 0xA6, 0x72, 0xAD, 0x00, 0x00, 0x00, 0x14, 0x52, 0x65, 0x67, 0x69, 0x6F, 0x6E, -0x20, 0x6F, 0x66, 0x20, 0x4D, 0x61, 0x67, 0x61, 0x6C, 0x6C, 0x61, 0x6E, 0x65, 0x73, +0x3A, 0x88, 0x00, 0xA6, 0x72, 0xAD, 0x00, 0x00, 0x00, 0x11, 0x4D, 0x61, 0x67, 0x61, 0x6C, 0x6C, +0x61, 0x6E, 0x65, 0x73, 0x20, 0x52, 0x65, 0x67, 0x69, 0x6F, 0x6E, /* America/Rainy_River */ 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -47037,7 +47264,7 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1C, 0x9A, 0x6C, 0x7D, 0xC8, 0xBF, 0x00, 0xCC, 0x48, 0x0D, 0x94, 0x44, 0x38, 0x0E, 0xAD, 0x13, 0xB8, 0x0F, 0x79, 0x73, 0x40, -0x10, 0x28, 0xCA, 0xC0, 0x10, 0xED, 0x3A, 0x40, 0x11, 0xAD, 0xBC, 0x48, 0x12, 0x45, 0x4A, 0xB8, +0x10, 0x28, 0xCA, 0xC0, 0x10, 0xA9, 0xFD, 0xC0, 0x11, 0xAD, 0xBC, 0x48, 0x12, 0x45, 0x4A, 0xB8, 0x13, 0x37, 0xEC, 0xC8, 0x14, 0x2D, 0x15, 0xB8, 0x28, 0x20, 0x76, 0xC8, 0x28, 0xDB, 0x9D, 0xB8, 0x29, 0xCB, 0x9C, 0xC8, 0x2A, 0xBE, 0x22, 0xB8, 0x2B, 0xAC, 0xD0, 0x48, 0x2C, 0x9F, 0x56, 0x38, 0x2D, 0x8E, 0x03, 0xC8, 0x2E, 0x80, 0x89, 0xB8, 0x2F, 0x6F, 0x37, 0x48, 0x30, 0x61, 0xBD, 0x38, @@ -47068,7 +47295,7 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0x9A, 0x6C, 0x7D, 0xC8, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xCC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x94, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAD, 0x13, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x79, 0x73, 0x40, 0x00, -0x00, 0x00, 0x00, 0x10, 0x28, 0xCA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x10, 0xED, 0x3A, 0x40, 0x00, +0x00, 0x00, 0x00, 0x10, 0x28, 0xCA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA9, 0xFD, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x11, 0xAD, 0xBC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x45, 0x4A, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37, 0xEC, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2D, 0x15, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x28, 0x20, 0x76, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x28, 0xDB, 0x9D, 0xB8, 0x00, @@ -65285,7 +65512,7 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1C, 0x9A, 0x6C, 0x7D, 0xC8, 0xBF, 0x00, 0xCC, 0x48, 0x0D, 0x94, 0x44, 0x38, 0x0E, 0xAD, 0x13, 0xB8, 0x0F, 0x79, 0x73, 0x40, -0x10, 0x28, 0xCA, 0xC0, 0x10, 0xED, 0x3A, 0x40, 0x11, 0xAD, 0xBC, 0x48, 0x12, 0x45, 0x4A, 0xB8, +0x10, 0x28, 0xCA, 0xC0, 0x10, 0xA9, 0xFD, 0xC0, 0x11, 0xAD, 0xBC, 0x48, 0x12, 0x45, 0x4A, 0xB8, 0x13, 0x37, 0xEC, 0xC8, 0x14, 0x2D, 0x15, 0xB8, 0x28, 0x20, 0x76, 0xC8, 0x28, 0xDB, 0x9D, 0xB8, 0x29, 0xCB, 0x9C, 0xC8, 0x2A, 0xBE, 0x22, 0xB8, 0x2B, 0xAC, 0xD0, 0x48, 0x2C, 0x9F, 0x56, 0x38, 0x2D, 0x8E, 0x03, 0xC8, 0x2E, 0x80, 0x89, 0xB8, 0x2F, 0x6F, 0x37, 0x48, 0x30, 0x61, 0xBD, 0x38, @@ -65316,7 +65543,7 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0x9A, 0x6C, 0x7D, 0xC8, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xCC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x94, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAD, 0x13, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x79, 0x73, 0x40, 0x00, -0x00, 0x00, 0x00, 0x10, 0x28, 0xCA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x10, 0xED, 0x3A, 0x40, 0x00, +0x00, 0x00, 0x00, 0x10, 0x28, 0xCA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA9, 0xFD, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x11, 0xAD, 0xBC, 0x48, 0x00, 0x00, 0x00, 0x00, 0x12, 0x45, 0x4A, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37, 0xEC, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2D, 0x15, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x28, 0x20, 0x76, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x28, 0xDB, 0x9D, 0xB8, 0x00, @@ -70844,4 +71071,4 @@ const unsigned char timelib_timezone_db_data_builtin[711319] = { }; #endif -const timelib_tzdb timezonedb_builtin = { "2025.1", 597, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; +const timelib_tzdb timezonedb_builtin = { "2025.2", 598, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 33663c01aaee7..4093f7a444cf2 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4618,6 +4618,7 @@ static zval *date_interval_get_property_ptr_ptr(zend_object *object, zend_string zend_string_equals_literal(name, "days") || zend_string_equals_literal(name, "invert") ) { /* Fallback to read_property. */ + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; ret = NULL; } else { ret = zend_std_get_property_ptr_ptr(object, name, type, cache_slot); diff --git a/ext/date/tests/DatePeriod_no_advance_on_valid.phpt b/ext/date/tests/DatePeriod_no_advance_on_valid.phpt index 6a8a9d0f5d04a..936861ca172c1 100644 --- a/ext/date/tests/DatePeriod_no_advance_on_valid.phpt +++ b/ext/date/tests/DatePeriod_no_advance_on_valid.phpt @@ -3,8 +3,8 @@ Date Period iterators do not advance on valid() --FILE-- getIterator(); diff --git a/ext/dba/dba.c b/ext/dba/dba.c index e4986e1cd2321..2205b13dfe050 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -57,6 +57,7 @@ ZEND_BEGIN_MODULE_GLOBALS(dba) const char *default_handler; const dba_handler *default_hptr; HashTable connections; + unsigned int connection_counter; ZEND_END_MODULE_GLOBALS(dba) ZEND_DECLARE_MODULE_GLOBALS(dba) @@ -571,7 +572,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) char *resource_key; size_t resource_key_len = spprintf(&resource_key, 0, - "dba_%d_%s_%s_%s", persistent, ZSTR_VAL(path), ZSTR_VAL(mode), handler_str ? ZSTR_VAL(handler_str) : "" + "dba_%d_%u_%s_%s_%s", persistent, persistent ? 0 : DBA_G(connection_counter)++, ZSTR_VAL(path), ZSTR_VAL(mode), handler_str ? ZSTR_VAL(handler_str) : "" ); if (persistent) { diff --git a/ext/dba/tests/dba_duplicateopen.phpt b/ext/dba/tests/dba_duplicateopen.phpt new file mode 100644 index 0000000000000..7068981f1a3c8 --- /dev/null +++ b/ext/dba/tests/dba_duplicateopen.phpt @@ -0,0 +1,34 @@ +--TEST-- +DBA open same read only file multiple times +--EXTENSIONS-- +dba +--SKIPIF-- + +--CONFLICTS-- +test.cdb +--FILE-- + +--EXPECT-- +database handler: cdb +1122 diff --git a/ext/dl_test/dl_test.c b/ext/dl_test/dl_test.c index 1d411c000ce23..7aebf54313385 100644 --- a/ext/dl_test/dl_test.c +++ b/ext/dl_test/dl_test.c @@ -92,10 +92,22 @@ PHP_METHOD(DlTest, test) RETURN_STR(retval); } +PHP_METHOD(DlTestSuperClass, test) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_NULL(); +} + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(dl_test) { + zend_class_entry *ce; + register_class_DlTest(); + ce = register_class_DlTestSuperClass(); + register_class_DlTestSubClass(ce); + register_class_DlTestAliasedClass(); /* Test backwards compatibility */ if (getenv("PHP_DL_TEST_USE_OLD_REGISTER_INI_ENTRIES")) { diff --git a/ext/dl_test/dl_test.stub.php b/ext/dl_test/dl_test.stub.php index cd8b3916bae2e..c2d8ff577780f 100644 --- a/ext/dl_test/dl_test.stub.php +++ b/ext/dl_test/dl_test.stub.php @@ -12,3 +12,15 @@ function dl_test_test2(string $str = ""): string {} class DlTest { public function test(string $str = ""): string {} } + +class DlTestSuperClass { + public int $a; + public function test(string $str = ""): string {} +} + +class DlTestSubClass extends DlTestSuperClass { +} + +/** @alias DlTestClassAlias */ +class DlTestAliasedClass { +} diff --git a/ext/dl_test/dl_test_arginfo.h b/ext/dl_test/dl_test_arginfo.h index 92d677acef36e..84c7c151ae79f 100644 --- a/ext/dl_test/dl_test_arginfo.h +++ b/ext/dl_test/dl_test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2dbacf5282b0f8e53923ac70495c2da43c7237e3 */ + * Stub hash: 0641a8eeff00e6c8083fe4a8639f970e3ba80db9 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_test1, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() @@ -10,9 +10,12 @@ ZEND_END_ARG_INFO() #define arginfo_class_DlTest_test arginfo_dl_test_test2 +#define arginfo_class_DlTestSuperClass_test arginfo_dl_test_test2 + ZEND_FUNCTION(dl_test_test1); ZEND_FUNCTION(dl_test_test2); ZEND_METHOD(DlTest, test); +ZEND_METHOD(DlTestSuperClass, test); static const zend_function_entry ext_functions[] = { ZEND_FE(dl_test_test1, arginfo_dl_test_test1) @@ -25,6 +28,11 @@ static const zend_function_entry class_DlTest_methods[] = { ZEND_FE_END }; +static const zend_function_entry class_DlTestSuperClass_methods[] = { + ZEND_ME(DlTestSuperClass, test, arginfo_class_DlTestSuperClass_test, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static zend_class_entry *register_class_DlTest(void) { zend_class_entry ce, *class_entry; @@ -34,3 +42,40 @@ static zend_class_entry *register_class_DlTest(void) return class_entry; } + +static zend_class_entry *register_class_DlTestSuperClass(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "DlTestSuperClass", class_DlTestSuperClass_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); + + zval property_a_default_value; + ZVAL_UNDEF(&property_a_default_value); + zend_string *property_a_name = zend_string_init("a", sizeof("a") - 1, 1); + zend_declare_typed_property(class_entry, property_a_name, &property_a_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_a_name); + + return class_entry; +} + +static zend_class_entry *register_class_DlTestSubClass(zend_class_entry *class_entry_DlTestSuperClass) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "DlTestSubClass", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DlTestSuperClass, 0); + + return class_entry; +} + +static zend_class_entry *register_class_DlTestAliasedClass(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "DlTestAliasedClass", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); + zend_register_class_alias("DlTestClassAlias", class_entry); + + return class_entry; +} diff --git a/ext/dom/document.c b/ext/dom/document.c index aed65630d2563..2abf6636713bf 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1669,14 +1669,28 @@ PHP_METHOD(Dom_XMLDocument, saveXml) } /* }}} end dom_document_savexml */ +static void dom_xinclude_strip_references_for_attributes(xmlNodePtr basep) +{ + for (xmlAttrPtr prop = basep->properties; prop; prop = prop->next) { + php_libxml_node_free_resource((xmlNodePtr) prop); + for (xmlNodePtr child = prop->children; child; child = child->next) { + php_libxml_node_free_resource(child); + } + } +} + static void dom_xinclude_strip_references(xmlNodePtr basep) { php_libxml_node_free_resource(basep); + dom_xinclude_strip_references_for_attributes(basep); xmlNodePtr current = basep->children; while (current) { php_libxml_node_free_resource(current); + if (current->type == XML_ELEMENT_NODE) { + dom_xinclude_strip_references_for_attributes(current); + } current = php_dom_next_in_tree_order(current, basep); } } diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 36ed3cd3e6f5f..5b9051f49b1b6 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -132,7 +132,7 @@ static void php_dom_iterator_current_key(zend_object_iterator *iter, zval *key) /* Only dtd named node maps, i.e. the ones based on a libxml hash table or attribute collections, * are keyed by the name because in that case the name is unique. */ if (!objmap->ht && objmap->nodetype != XML_ATTRIBUTE_NODE) { - ZVAL_LONG(key, iter->index); + ZVAL_LONG(key, iterator->index); } else { dom_object *intern = Z_DOMOBJ_P(&iterator->curobj); @@ -179,6 +179,8 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ return; } + iterator->index++; + dom_object *intern = Z_DOMOBJ_P(&iterator->curobj); dom_nnodemap_object *objmap = php_dom_iterator_get_nnmap(iterator); @@ -203,7 +205,7 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ php_dom_mark_cache_tag_up_to_date_from_doc_ref(&iterator->cache_tag, intern->document); curnode = dom_fetch_first_iteration_item(objmap); zend_ulong index = 0; - while (curnode != NULL && index++ < iter->index) { + while (curnode != NULL && index++ < iterator->index) { curnode = curnode->next; } } else { @@ -224,15 +226,15 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ previndex = 0; curnode = php_dom_first_child_of_container_node(basenode); } else { - previndex = iter->index - 1; + previndex = iterator->index - 1; curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node; } curnode = dom_get_elements_by_tag_name_ns_raw( - basenode, curnode, objmap->ns, objmap->local, objmap->local_lower, &previndex, iter->index); + basenode, curnode, objmap->ns, objmap->local, objmap->local_lower, &previndex, iterator->index); } } } else { - curnode = php_dom_libxml_hash_iter(objmap, iter->index); + curnode = php_dom_libxml_hash_iter(objmap, iterator->index); } } @@ -269,15 +271,13 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } - iterator = emalloc(sizeof(php_dom_iterator)); + iterator = emalloc(sizeof(*iterator)); + memset(iterator, 0, sizeof(*iterator)); zend_iterator_init(&iterator->intern); - iterator->cache_tag.modification_nr = 0; ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object)); iterator->intern.funcs = &php_dom_iterator_funcs; - ZVAL_UNDEF(&iterator->curobj); - intern = Z_DOMOBJ_P(object); objmap = (dom_nnodemap_object *)intern->ptr; if (objmap != NULL) { diff --git a/ext/dom/html5_parser.c b/ext/dom/html5_parser.c index 0d7d2b9e7249d..f1dc2db53b25b 100644 --- a/ext/dom/html5_parser.c +++ b/ext/dom/html5_parser.c @@ -138,7 +138,9 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert( * If a prefix:name format is used, then the local name will be "prefix:name" and the prefix will be empty. * There is however still somewhat of a concept of namespaces. There are three: HTML (the default), SVG, and MATHML. */ lxb_dom_element_t *element = lxb_dom_interface_element(node); - const lxb_char_t *name = lxb_dom_element_local_name(element, NULL); + const lxb_char_t *name = lxb_dom_element_qualified_name(element, NULL); + ZEND_ASSERT(!element->node.prefix); + xmlNodePtr lxml_element = xmlNewDocNode(lxml_doc, NULL, name, NULL); if (UNEXPECTED(lxml_element == NULL)) { retval = LEXBOR_LIBXML2_BRIDGE_STATUS_OOM; @@ -203,7 +205,13 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert( for (lxb_dom_attr_t *attr = element->first_attr; attr != NULL; attr = attr->next) { /* Same namespace remark as for elements */ size_t local_name_length, value_length; - const lxb_char_t *local_name = lxb_dom_attr_local_name(attr, &local_name_length); + const lxb_char_t *local_name = lxb_dom_attr_qualified_name(attr, &local_name_length); + if (attr->node.prefix) { + const char *pos = strchr((const char *) local_name, ':'); + if (EXPECTED(pos)) { + local_name = (const lxb_char_t *) pos + 1; + } + } const lxb_char_t *value = lxb_dom_attr_value(attr, &value_length); if (UNEXPECTED(local_name_length >= INT_MAX || value_length >= INT_MAX)) { diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 6f9d87feebfb4..819d22712ebfc 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -362,6 +362,7 @@ static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, in return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; return NULL; } @@ -371,13 +372,14 @@ static zend_always_inline const dom_prop_handler *dom_get_prop_handler(const dom if (obj->prop_handler != NULL) { if (cache_slot && *cache_slot == obj->prop_handler) { - hnd = *(cache_slot + 1); + hnd = cache_slot[1]; } if (!hnd) { hnd = zend_hash_find_ptr(obj->prop_handler, name); if (cache_slot) { - *cache_slot = obj->prop_handler; - *(cache_slot + 1) = (void *) hnd; + cache_slot[0] = obj->prop_handler; + cache_slot[1] = (void *) hnd; + cache_slot[2] = NULL; } } } diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 56fdc244f8cfb..bb0d83676dca1 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -97,6 +97,9 @@ typedef struct { zend_object_iterator intern; zval curobj; HashPosition pos; + /* intern->index is only updated for FE_* opcodes, not for e.g. unpacking, + * yet we need to track the position of the node relative to the start. */ + zend_ulong index; php_libxml_cache_tag cache_tag; } php_dom_iterator; diff --git a/ext/dom/tests/DOMDocument_loadHTMLfile_variation1.phpt b/ext/dom/tests/DOMDocument_loadHTMLfile_variation1.phpt index b3ff73d1f3441..74c27e93d9dcc 100644 --- a/ext/dom/tests/DOMDocument_loadHTMLfile_variation1.phpt +++ b/ext/dom/tests/DOMDocument_loadHTMLfile_variation1.phpt @@ -6,6 +6,10 @@ Verifies that an warning message is showed if an empty document is loaded Antonio Diaz Ruiz --EXTENSIONS-- dom +--SKIPIF-- += 21400) die("skip libxml >= 2.14 no longer has this non-standard warning"); +?> --FILE-- U+0000 loadHTML($html); print($doc->saveHTML()); ?> ---EXPECT-- +--EXPECTF-- -U+0000 +U+0000 %r(�|)%r diff --git a/ext/dom/tests/bug78025.phpt b/ext/dom/tests/bug78025.phpt index 910f7728c3c2c..d6f84939c5f14 100644 --- a/ext/dom/tests/bug78025.phpt +++ b/ext/dom/tests/bug78025.phpt @@ -6,9 +6,8 @@ dom "; $dom = new DOMDocument; -$dom->loadHTML($htm); +$dom->loadHTML($htm, LIBXML_NOERROR); var_dump($dom->doctype->name); ?> --EXPECTF-- -Warning: DOMDocument::loadHTML(): htmlParseDocTypeDecl : no DOCTYPE name ! in Entity, line: 1 in %s on line %d string(0) "" diff --git a/ext/dom/tests/bug80268_2.phpt b/ext/dom/tests/bug80268_2.phpt index af8cf7faca5a5..dcde29e6835a7 100644 --- a/ext/dom/tests/bug80268_2.phpt +++ b/ext/dom/tests/bug80268_2.phpt @@ -9,13 +9,13 @@ if (LIBXML_VERSION < 20912) die('skip For libxml2 >= 2.9.12 only'); --FILE-- loadHTML("

foo\0bar

"); +$doc->loadHTML("

foo\0bar

", LIBXML_NOERROR); $html = $doc->saveHTML(); var_dump(strpos($html, '

foo

') !== false); file_put_contents(__DIR__ . '/80268.html', "

foo\0bar

"); $doc = new DOMDocument; -$doc->loadHTMLFile(__DIR__ . '/80268.html'); +$doc->loadHTMLFile(__DIR__ . '/80268.html', LIBXML_NOERROR); $html = $doc->saveHTML(); var_dump(strpos($html, '

foo

') !== false); ?> @@ -24,8 +24,5 @@ var_dump(strpos($html, '

foo

') !== false); unlink(__DIR__ . '/80268.html'); ?> --EXPECTF-- -Warning: DOMDocument::loadHTML(): Char 0x0 out of allowed range in Entity, line: 1 in %s on line %d bool(false) - -Warning: DOMDocument::loadHTMLFile(): Char 0x0 out of allowed range in %s on line %d bool(false) diff --git a/ext/dom/tests/gh16535.phpt b/ext/dom/tests/gh16535.phpt index 1c8d282303c88..adb1dfa91f204 100644 --- a/ext/dom/tests/gh16535.phpt +++ b/ext/dom/tests/gh16535.phpt @@ -14,7 +14,7 @@ try { } catch (DOMException $e) { echo $e->getMessage(), "\n"; } -$v2->loadHTML("oU"); +$v2->loadHTML("

oU

"); echo $v2->saveXML(); ?> diff --git a/ext/dom/tests/gh17847.phpt b/ext/dom/tests/gh17847.phpt index c32263bfe240f..b2c4caff2fc75 100644 --- a/ext/dom/tests/gh17847.phpt +++ b/ext/dom/tests/gh17847.phpt @@ -13,7 +13,7 @@ $doc->loadXML(<< -

garbage

+

garbage

@@ -22,20 +22,31 @@ XML); $xpath = new DOMXPath($doc); $garbage = []; -foreach ($xpath->query('//p') as $entry) +foreach ($xpath->query('//p') as $entry) { $garbage[] = $entry; + foreach ($entry->attributes as $attr) { + $garbage[] = $attr; + foreach ($attr->childNodes as $child) { + $garbage[] = $child; + } + } +} @$doc->xinclude(); foreach ($garbage as $node) { - try { - var_dump($node->localName); - } catch (DOMException $e) { - echo $e->getMessage(), "\n"; - } + try { + var_dump($node->localName); + } catch (DOMException $e) { + echo $e->getMessage(), "\n"; + } } ?> --EXPECT-- Invalid State Error Invalid State Error Invalid State Error +Invalid State Error +Invalid State Error +Invalid State Error +Invalid State Error diff --git a/ext/dom/tests/gh17991.phpt b/ext/dom/tests/gh17991.phpt new file mode 100644 index 0000000000000..4fc2c5b4ec1eb --- /dev/null +++ b/ext/dom/tests/gh17991.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-17991 (Assertion failure dom_attr_value_write) +--EXTENSIONS-- +dom +--FILE-- +value = new Test); +} +$box = new Box(); +test($box); +test($attr); +?> +--EXPECTF-- +object(Test)#%d (0) { +} + +Fatal error: Uncaught TypeError: Cannot assign Test to property DOMAttr::$value of type string in %s:%d +Stack trace: +#0 %s(%d): test(Object(DOMAttr)) +#1 {main} + thrown in %s on line %d diff --git a/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_001.phpt b/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_001.phpt new file mode 100644 index 0000000000000..47212cb34100a --- /dev/null +++ b/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_001.phpt @@ -0,0 +1,60 @@ +--TEST-- +GHSA-p3x9-6h7p-cgfc: libxml streams use wrong `content-type` header when requesting a redirected resource (Basic) +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- + + + + GHSA-p3x9-6h7p-cgfc + + + + + + +

GHSA-p3x9-6h7p-cgfc

+ + + EOT; + // Intentionally using non-standard casing for content-type to verify it is matched not case sensitively. + yield "data://text/plain,HTTP/1.1 200 OK\r\nconteNt-tyPe: text/html; charset=utf-8\r\n\r\n{$xml}"; +} + +['pid' => $pid, 'uri' => $uri] = http_server('genResponses', $output); +$document = new \DOMDocument(); +$document->loadHTMLFile($uri); + +$h1 = $document->getElementsByTagName('h1'); +var_dump($h1->length); +var_dump($document->saveHTML()); +http_server_kill($pid); +?> +--EXPECT-- +int(1) +string(266) " + + + GHSA-p3x9-6h7p-cgfc + + + + + + +

GHSA-p3x9-6h7p-cgfc

+ + +" diff --git a/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_002.phpt b/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_002.phpt new file mode 100644 index 0000000000000..a7eff3b9a8b76 --- /dev/null +++ b/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +GHSA-p3x9-6h7p-cgfc: libxml streams use wrong `content-type` header when requesting a redirected resource (Missing content-type) +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- + + + + GHSA-p3x9-6h7p-cgfc + + + + + + +

GHSA-p3x9-6h7p-cgfc

+ + + EOT; + // Missing content-type in actual response. + yield "data://text/plain,HTTP/1.1 200 OK\r\n\r\n{$xml}"; +} + +['pid' => $pid, 'uri' => $uri] = http_server('genResponses', $output); +$document = new \DOMDocument(); +$document->loadHTMLFile($uri); + +$h1 = $document->getElementsByTagName('h1'); +var_dump($h1->length); +var_dump($document->saveHTML()); +http_server_kill($pid); +?> +--EXPECT-- +int(1) +string(266) " + + + GHSA-p3x9-6h7p-cgfc + + + + + + +

GHSA-p3x9-6h7p-cgfc

+ + +" diff --git a/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_003.phpt b/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_003.phpt new file mode 100644 index 0000000000000..178b35f3525a5 --- /dev/null +++ b/ext/dom/tests/ghsa-p3x9-6h7p-cgfc_003.phpt @@ -0,0 +1,60 @@ +--TEST-- +GHSA-p3x9-6h7p-cgfc: libxml streams use wrong `content-type` header when requesting a redirected resource (Reason with colon) +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- + + + + GHSA-p3x9-6h7p-cgfc + + + + + + +

GHSA-p3x9-6h7p-cgfc

+ + + EOT; + // Missing content-type in actual response. + yield "data://text/plain,HTTP/1.1 200 OK: This is fine\r\n\r\n{$xml}"; +} + +['pid' => $pid, 'uri' => $uri] = http_server('genResponses', $output); +$document = new \DOMDocument(); +$document->loadHTMLFile($uri); + +$h1 = $document->getElementsByTagName('h1'); +var_dump($h1->length); +var_dump($document->saveHTML()); +http_server_kill($pid); +?> +--EXPECT-- +int(1) +string(266) " + + + GHSA-p3x9-6h7p-cgfc + + + + + + +

GHSA-p3x9-6h7p-cgfc

+ + +" diff --git a/ext/dom/tests/modern/common/unpacking_foreach.phpt b/ext/dom/tests/modern/common/unpacking_foreach.phpt new file mode 100644 index 0000000000000..b2bb301ccdc11 --- /dev/null +++ b/ext/dom/tests/modern/common/unpacking_foreach.phpt @@ -0,0 +1,30 @@ +--TEST-- +unpacking vs foreach in new DOM +--EXTENSIONS-- +dom +--FILE-- +Hi

hi

", + options: LIBXML_NOERROR, +); + +foreach ($html->body->childNodes as $node) { + echo $node->localName, "\n"; +} + +echo "---\n"; + +foreach ([...$html->body->childNodes] as $node) { + echo $node->localName, "\n"; +} + +?> +--EXPECT-- +h1 +p +--- +h1 +p diff --git a/ext/dom/tests/modern/html/parser/gh18090.phpt b/ext/dom/tests/modern/html/parser/gh18090.phpt new file mode 100644 index 0000000000000..c32f5ddb51336 --- /dev/null +++ b/ext/dom/tests/modern/html/parser/gh18090.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-18090 (Svg attributes and tag names are being lowercased) +--EXTENSIONS-- +dom +--FILE-- +', LIBXML_NOERROR)->saveHTML(), "\n"; + +echo \Dom\HTMLDocument::createFromString('', LIBXML_NOERROR)->saveHTML(), "\n"; + +echo \Dom\HTMLDocument::createFromString('', LIBXML_NOERROR)->querySelector('svg')->attributes[0]->name, "\n"; +?> +--EXPECT-- + + +viewBox diff --git a/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt b/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt index 7e78460454e60..b4c07c6fb3bb8 100644 --- a/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt +++ b/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt @@ -47,7 +47,7 @@ echo $dom->saveXml(); svg http://www.w3.org/2000/svg Attribute: width (NONE) Attribute: height (NONE) - Attribute: viewbox (NONE) + Attribute: viewBox (NONE) rect http://www.w3.org/2000/svg Attribute: id (NONE) Attribute: x (NONE) @@ -65,7 +65,7 @@ svg http://www.w3.org/1998/Math/MathML Test - + @@ -85,7 +85,7 @@ svg http://www.w3.org/1998/Math/MathML Test - + diff --git a/ext/dom/tests/unpack_foreach_behaviour.phpt b/ext/dom/tests/unpack_foreach_behaviour.phpt new file mode 100644 index 0000000000000..42fe896d9f786 --- /dev/null +++ b/ext/dom/tests/unpack_foreach_behaviour.phpt @@ -0,0 +1,31 @@ +--TEST-- +Unpacking vs foreach behaviour +--EXTENSIONS-- +dom +--FILE-- +loadXML(''); + +echo "--- By foreach: ---\n"; + +foreach ($dom->documentElement->getElementsByTagName('*') as $node) { + var_dump($node->localName); +} + +echo "--- By unpacking: ---\n"; + +$iter = $dom->documentElement->getElementsByTagName('*'); +foreach ([...$iter] as $node) { + var_dump($node->localName); +} + +?> +--EXPECT-- +--- By foreach: --- +string(1) "a" +string(1) "b" +--- By unpacking: --- +string(1) "a" +string(1) "b" diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 962041232c618..daf1f0c67a421 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -3748,7 +3748,7 @@ PHP_FUNCTION(imageconvolution) } for (i=0; i<3; i++) { - if ((var = zend_hash_index_find(Z_ARRVAL_P(hash_matrix), (i))) != NULL && Z_TYPE_P(var) == IS_ARRAY) { + if ((var = zend_hash_index_find_deref(Z_ARRVAL_P(hash_matrix), (i))) != NULL && Z_TYPE_P(var) == IS_ARRAY) { if (zend_hash_num_elements(Z_ARRVAL_P(var)) != 3 ) { zend_argument_value_error(2, "must be a 3x3 array, matrix[%d] only has %d elements", i, zend_hash_num_elements(Z_ARRVAL_P(var))); RETURN_THROWS(); @@ -4061,7 +4061,7 @@ PHP_FUNCTION(imageaffine) } for (i = 0; i < nelems; i++) { - if ((zval_affine_elem = zend_hash_index_find(Z_ARRVAL_P(z_affine), i)) != NULL) { + if ((zval_affine_elem = zend_hash_index_find_deref(Z_ARRVAL_P(z_affine), i)) != NULL) { switch (Z_TYPE_P(zval_affine_elem)) { case IS_LONG: affine[i] = Z_LVAL_P(zval_affine_elem); @@ -4239,7 +4239,7 @@ PHP_FUNCTION(imageaffinematrixconcat) } for (i = 0; i < 6; i++) { - if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m1), i)) != NULL) { + if ((tmp = zend_hash_index_find_deref(Z_ARRVAL_P(z_m1), i)) != NULL) { switch (Z_TYPE_P(tmp)) { case IS_LONG: m1[i] = Z_LVAL_P(tmp); @@ -4256,7 +4256,7 @@ PHP_FUNCTION(imageaffinematrixconcat) } } - if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m2), i)) != NULL) { + if ((tmp = zend_hash_index_find_deref(Z_ARRVAL_P(z_m2), i)) != NULL) { switch (Z_TYPE_P(tmp)) { case IS_LONG: m2[i] = Z_LVAL_P(tmp); diff --git a/ext/gd/tests/gh17984.phpt b/ext/gd/tests/gh17984.phpt new file mode 100644 index 0000000000000..c46c455799e0f --- /dev/null +++ b/ext/gd/tests/gh17984.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-17984: array of references handling +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +object(GdImage)#2 (0) { +} +array(6) { + [0]=> + float(2028) + [1]=> + float(46) + [2]=> + float(138) + [3]=> + float(4) + [4]=> + float(233) + [5]=> + float(7) +} +bool(true) +bool(true) +bool(true) diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c index 858f1ee3b50de..339ab18b1d66e 100644 --- a/ext/intl/converter/converter.c +++ b/ext/intl/converter/converter.c @@ -754,13 +754,13 @@ PHP_METHOD(UConverter, transcode) { zval *tmpzval; if (U_SUCCESS(error) && - (tmpzval = zend_hash_str_find(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst") - 1)) != NULL && + (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst") - 1)) != NULL && Z_TYPE_P(tmpzval) == IS_STRING) { error = U_ZERO_ERROR; ucnv_setSubstChars(src_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); } if (U_SUCCESS(error) && - (tmpzval = zend_hash_str_find(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst") - 1)) != NULL && + (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst") - 1)) != NULL && Z_TYPE_P(tmpzval) == IS_STRING) { error = U_ZERO_ERROR; ucnv_setSubstChars(dest_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); diff --git a/ext/intl/dateformat/dateformat_format.c b/ext/intl/dateformat/dateformat_format.c index 0d01323353026..f4ef8a40d6458 100644 --- a/ext/intl/dateformat/dateformat_format.c +++ b/ext/intl/dateformat/dateformat_format.c @@ -64,7 +64,7 @@ static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo, return result; } - if ((ele_value = zend_hash_str_find(hash_arr, key_name, strlen(key_name))) != NULL) { + if ((ele_value = zend_hash_str_find_deref(hash_arr, key_name, strlen(key_name))) != NULL) { if(Z_TYPE_P(ele_value) != IS_LONG) { spprintf(&message, 0, "datefmt_format: parameter array contains " "a non-integer element for key '%s'", key_name); diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 373d71d263604..b2891de9d4aca 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -807,7 +807,7 @@ static int append_key_value(smart_str* loc_name, HashTable* hash_arr, char* key_ { zval *ele_value; - if ((ele_value = zend_hash_str_find(hash_arr , key_name, strlen(key_name))) != NULL ) { + if ((ele_value = zend_hash_str_find_deref(hash_arr , key_name, strlen(key_name))) != NULL ) { if(Z_TYPE_P(ele_value)!= IS_STRING ){ /* element value is not a string */ return FAILURE; @@ -850,7 +850,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, int isFirstSubtag = 0; /* Variant/ Extlang/Private etc. */ - if ((ele_value = zend_hash_str_find( hash_arr , key_name , strlen(key_name))) != NULL) { + if ((ele_value = zend_hash_str_find_deref( hash_arr , key_name , strlen(key_name))) != NULL) { if( Z_TYPE_P(ele_value) == IS_STRING ){ add_prefix( loc_name , key_name); @@ -862,6 +862,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, zval *data; ZEND_HASH_FOREACH_VAL(arr, data) { + ZVAL_DEREF(data); if(Z_TYPE_P(data) != IS_STRING) { return FAILURE; } @@ -893,7 +894,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, isFirstSubtag = 0; for( i=0 ; i< max_value; i++ ){ snprintf( cur_key_name , 30, "%s%d", key_name , i); - if ((ele_value = zend_hash_str_find( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) { + if ((ele_value = zend_hash_str_find_deref( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) { if( Z_TYPE_P(ele_value)!= IS_STRING ){ /* variant is not a string */ return FAILURE; @@ -1426,6 +1427,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, char **cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)); ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) { + ZVAL_DEREF(ele_value); /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ if(Z_TYPE_P(ele_value)!= IS_STRING) { /* element value is not a string */ diff --git a/ext/intl/tests/dateformat_format_references.phpt b/ext/intl/tests/dateformat_format_references.phpt new file mode 100644 index 0000000000000..da1a52955f121 --- /dev/null +++ b/ext/intl/tests/dateformat_format_references.phpt @@ -0,0 +1,23 @@ +--TEST-- +Fix dateformat_format() with array argument with values as references. +--SKIPIF-- + +--FILE-- + &$a , + 'tm_min' => 3, + 'tm_hour' => 19, + 'tm_mday' => 3, + 'tm_mon' => 3, + 'tm_year' => 105, +); +$fmt = datefmt_create('en_US', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'America/New_York', IntlDateFormatter::GREGORIAN); +$formatted = datefmt_format($fmt , $localtime_arr); +var_dump($formatted); +?> +--EXPECTF-- +string(%d) "Sunday, April 3, 2005 at 7:03:24%aPM Eastern Daylight Time" diff --git a/ext/intl/tests/locale_compose_lookup_references.phpt b/ext/intl/tests/locale_compose_lookup_references.phpt new file mode 100644 index 0000000000000..f6a202f7512fa --- /dev/null +++ b/ext/intl/tests/locale_compose_lookup_references.phpt @@ -0,0 +1,29 @@ +--TEST-- +locale_compose()/locale_lookup() with values as references. +--EXTENSIONS-- +intl +--FILE-- + 'en', Locale::REGION_TAG => &$en]; + +var_dump(locale_compose($data)); + +$data = [ + 'language' => 'de', + 'script' => 'Hans', + 'region' => 'DE', + 'variant2' => 'fr', + 'variant1' => &$en, + 'private1' => 'private1', + 'private2' => 'private2', + ]; +var_dump(locale_compose($data)); +$data = ['de', &$en]; +var_dump(locale_lookup($data, "en", false, "en")); +?> +--EXPECT-- +string(5) "en_en" +string(36) "de_Hans_DE_en_fr_x_private1_private2" +string(2) "en" diff --git a/ext/intl/tests/locale_get_display_name8.phpt b/ext/intl/tests/locale_get_display_name8.phpt index e8c1ed958ac1c..aa91ee4c3b8ca 100644 --- a/ext/intl/tests/locale_get_display_name8.phpt +++ b/ext/intl/tests/locale_get_display_name8.phpt @@ -112,9 +112,9 @@ disp_locale=fr : display_name=slovène #Italie, NEDIS_KIRTI# disp_locale=de : display_name=Slowenisch #Italien, NEDIS_KIRTI# ----------------- locale='sl_IT_nedis-a-kirti-x-xyz' -disp_locale=en : display_name=Slovenian #Italy, NEDIS_A_KIRTI_X_XYZ# -disp_locale=fr : display_name=slovène #Italie, NEDIS_A_KIRTI_X_XYZ# -disp_locale=de : display_name=Slowenisch #Italien, NEDIS_A_KIRTI_X_XYZ# +disp_locale=en : display_name=Slovenian #Italy, NEDIS_A_KIRTI(_X_XYZ)?# +disp_locale=fr : display_name=slovène #Italie, NEDIS_A_KIRTI(_X_XYZ)?# +disp_locale=de : display_name=Slowenisch #Italien, NEDIS_A_KIRTI(_X_XYZ)?# ----------------- locale='sl_IT_rozaj' disp_locale=en : display_name=Slovenian #Italy, Resian# @@ -317,9 +317,9 @@ disp_locale=fr : display_name=anglais #États-Unis, attribute=islamcal# disp_locale=de : display_name=Englisch #Vereinigte Staaten, attribute=islamcal# ----------------- locale='zh-CN-a-myExt-x-private' -disp_locale=en : display_name=Chinese #China(, A_MYEXT_X_PRIVATE)?, a=myext, Private-Use=private# -disp_locale=fr : display_name=chinois #Chine(, A_MYEXT_X_PRIVATE)?, a=myext, usage privé=private# -disp_locale=de : display_name=Chinesisch #China(, A_MYEXT_X_PRIVATE)?, a=myext, Privatnutzung=private# +disp_locale=en : display_name=Chinese #China(, A_MYEXT(_X_PRIVATE)?)?, a=myext, Private-Use=private# +disp_locale=fr : display_name=chinois #Chine(, A_MYEXT(_X_PRIVATE)?)?, a=myext, usage privé=private# +disp_locale=de : display_name=Chinesisch #China(, A_MYEXT(_X_PRIVATE)?)?, a=myext, Privatnutzung=private# ----------------- locale='en-a-myExt-b-another' disp_locale=en : display_name=English #(A_MYEXT_B_ANOTHER, )?a=myext, b=another# diff --git a/ext/intl/tests/locale_get_display_variant2.phpt b/ext/intl/tests/locale_get_display_variant2.phpt index e56154902dde9..8e815e8c4e52a 100644 --- a/ext/intl/tests/locale_get_display_variant2.phpt +++ b/ext/intl/tests/locale_get_display_variant2.phpt @@ -248,9 +248,9 @@ disp_locale=fr : display_variant= disp_locale=de : display_variant= ----------------- locale='zh-CN-a-myExt-x-private' -disp_locale=en : display_variant=(A_MYEXT_X_PRIVATE)? -disp_locale=fr : display_variant=(A_MYEXT_X_PRIVATE)? -disp_locale=de : display_variant=(A_MYEXT_X_PRIVATE)? +disp_locale=en : display_variant=(A_MYEXT(_X_PRIVATE)?)? +disp_locale=fr : display_variant=(A_MYEXT(_X_PRIVATE)?)? +disp_locale=de : display_variant=(A_MYEXT(_X_PRIVATE)?)? ----------------- locale='en-a-myExt-b-another' disp_locale=en : display_variant=((A_)?MYEXT_B_ANOTHER)? diff --git a/ext/intl/tests/uconverter_transcode_references.phpt b/ext/intl/tests/uconverter_transcode_references.phpt new file mode 100644 index 0000000000000..a2b1be20d1dfe --- /dev/null +++ b/ext/intl/tests/uconverter_transcode_references.phpt @@ -0,0 +1,22 @@ +--TEST-- +UConverter::transcode issue with substitutes values as references +--EXTENSIONS-- +intl +--FILE-- + '?', 'to_subst' => &$subst); +var_dump(UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts)); +$opts = array('from_subst' => &$subst, 'to_subst' => '?'); +var_dump(UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts)); +// should yield the same results +$opts = array('from_subst' => '?', 'to_subst' => '??'); +var_dump(UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts)); +$opts = array('from_subst' => '??', 'to_subst' => '?'); +var_dump(UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts)); +?> +--EXPECT-- +bool(false) +string(23) "This is an ascii string" +bool(false) +string(23) "This is an ascii string" diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 7c44a7f5c7a71..4145bc2b6154a 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -283,13 +283,12 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) { continue; } - zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp); + data = zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp); if (EG(exception)) { PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc); zend_release_properties(prop_ht); return FAILURE; } - data = &tmp; } if (need_comma) { diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 67b01c0ec4472..20245ed56961b 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -2278,7 +2278,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_P(value); } else { if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(value))) { - zend_argument_value_error(3, "must be an array with numeric keys"); + zend_argument_value_error(3, "attribute \"%s\" must be an array with numeric keys", ZSTR_VAL(attribute)); RETVAL_FALSE; num_berval[i] = 0; num_attribs = i + 1; diff --git a/ext/ldap/tests/ldap_add_error.phpt b/ext/ldap/tests/ldap_add_error.phpt index 5036b3091e835..209a7fb165dc5 100644 --- a/ext/ldap/tests/ldap_add_error.phpt +++ b/ext/ldap/tests/ldap_add_error.phpt @@ -104,7 +104,7 @@ Warning: ldap_add(): Add: Already exists in %s on line %d bool(false) string(14) "Already exists" int(68) -ldap_add(): Argument #3 ($entry) must be an array with numeric keys +ldap_add(): Argument #3 ($entry) attribute "objectClass" must be an array with numeric keys Warning: ldap_add(): Add: Undefined attribute type in %s on line %d bool(false) diff --git a/ext/libxml/mime_sniff.c b/ext/libxml/mime_sniff.c index 79ce1dc46b5e0..0ca032f9b795e 100644 --- a/ext/libxml/mime_sniff.c +++ b/ext/libxml/mime_sniff.c @@ -308,11 +308,21 @@ PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_stream(const php_strea if (Z_TYPE(s->wrapperdata) == IS_ARRAY) { zval *header; - ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) { - const char buf[] = "Content-Type:"; - if (Z_TYPE_P(header) == IS_STRING && - !zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) { - return php_libxml_sniff_charset_from_string(Z_STRVAL_P(header) + sizeof(buf) - 1, Z_STRVAL_P(header) + Z_STRLEN_P(header)); + /* Scan backwards: The header array might contain the headers for multiple responses, if + * a redirect was followed. + */ + ZEND_HASH_REVERSE_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) { + if (Z_TYPE_P(header) == IS_STRING) { + /* If no colon is found in the header, we assume it's the HTTP status line and bail out. */ + char *colon = memchr(Z_STRVAL_P(header), ':', Z_STRLEN_P(header)); + char *space = memchr(Z_STRVAL_P(header), ' ', Z_STRLEN_P(header)); + if (colon == NULL || space < colon) { + return NULL; + } + + if (zend_string_starts_with_literal_ci(Z_STR_P(header), "content-type:")) { + return php_libxml_sniff_charset_from_string(Z_STRVAL_P(header) + strlen("content-type:"), Z_STRVAL_P(header) + Z_STRLEN_P(header)); + } } } ZEND_HASH_FOREACH_END(); } diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index cd8a77d5c773a..e848f21615bca 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1572,7 +1572,9 @@ PHP_FUNCTION(mb_output_handler) char *mimetype = NULL; /* Analyze mime type */ - if (SG(sapi_headers).mimetype && _php_mb_match_regex(MBSTRG(http_output_conv_mimetypes), SG(sapi_headers).mimetype, strlen(SG(sapi_headers).mimetype))) { + if (SG(sapi_headers).mimetype + && MBSTRG(http_output_conv_mimetypes) + && _php_mb_match_regex(MBSTRG(http_output_conv_mimetypes), SG(sapi_headers).mimetype, strlen(SG(sapi_headers).mimetype))) { char *s; if ((s = strchr(SG(sapi_headers).mimetype, ';')) == NULL) { mimetype = estrdup(SG(sapi_headers).mimetype); diff --git a/ext/mbstring/tests/gh17989.phpt b/ext/mbstring/tests/gh17989.phpt new file mode 100644 index 0000000000000..40efd5866c171 --- /dev/null +++ b/ext/mbstring/tests/gh17989.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17989 (mb_output_handler crash with unset http_output_conv_mimetypes) +--EXTENSIONS-- +mbstring +--INI-- +mbstring.http_output_conv_mimetypes= +--FILE-- + +--EXPECT-- +set mime type via this echo +hi diff --git a/ext/mysqli/tests/bug73462.phpt b/ext/mysqli/tests/bug73462.phpt index 7a747e8a93b79..7a2f126cedde3 100644 --- a/ext/mysqli/tests/bug73462.phpt +++ b/ext/mysqli/tests/bug73462.phpt @@ -12,7 +12,7 @@ require_once 'skipifconnectfailure.inc'; /* Initial persistent connection */ $mysql_1 = new mysqli('p:'.$host, $user, $passwd, $db, $port); - $result = $mysql_1->query("SHOW STATUS LIKE 'Connections'"); + $result = $mysql_1->query("SELECT CONNECTION_ID()"); $c1 = $result->fetch_row(); $result->free(); $mysql_1->close(); @@ -28,7 +28,7 @@ require_once 'skipifconnectfailure.inc'; /* Re-use persistent connection */ $mysql_3 = new mysqli('p:'.$host, $user, $passwd, $db, $port); $error = mysqli_connect_errno(); - $result = $mysql_3->query("SHOW STATUS LIKE 'Connections'"); + $result = $mysql_3->query("SELECT CONNECTION_ID()"); $c3 = $result->fetch_row(); $result->free(); $mysql_3->close(); diff --git a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt index 69fc427001fd0..594980ec0f829 100644 --- a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt +++ b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt @@ -122,22 +122,27 @@ func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", "99999999.99", "99999999. func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400); // don't care about date() strict TZ warnings... -func_mysqli_fetch_all($link, $engine, "DATE", @date('Y-m-d'), @date('Y-m-d'), 410); -func_mysqli_fetch_all($link, $engine, "DATE NOT NULL", @date('Y-m-d'), @date('Y-m-d'), 420); +$date = @date('Y-m-d'); +$datetime = @date('Y-m-d H:i:s'); +$time = @date('H:i:s'); +$year = @date('Y'); + +func_mysqli_fetch_all($link, $engine, "DATE", $date, $date, 410); +func_mysqli_fetch_all($link, $engine, "DATE NOT NULL", $date, $date, 420); func_mysqli_fetch_all($link, $engine, "DATE", NULL, NULL, 430); -func_mysqli_fetch_all($link, $engine, "DATETIME", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 440); -func_mysqli_fetch_all($link, $engine, "DATETIME NOT NULL", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 450); +func_mysqli_fetch_all($link, $engine, "DATETIME", $datetime, $datetime, 440); +func_mysqli_fetch_all($link, $engine, "DATETIME NOT NULL", $datetime, $datetime, 450); func_mysqli_fetch_all($link, $engine, "DATETIME", NULL, NULL, 460); -func_mysqli_fetch_all($link, $engine, "TIMESTAMP", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 470); +func_mysqli_fetch_all($link, $engine, "TIMESTAMP", $datetime, $datetime, 470); -func_mysqli_fetch_all($link, $engine, "TIME", @date('H:i:s'), @date('H:i:s'), 480); -func_mysqli_fetch_all($link, $engine, "TIME NOT NULL", @date('H:i:s'), @date('H:i:s'), 490); +func_mysqli_fetch_all($link, $engine, "TIME", $time, $time, 480); +func_mysqli_fetch_all($link, $engine, "TIME NOT NULL", $time, $time, 490); func_mysqli_fetch_all($link, $engine, "TIME", NULL, NULL, 500); -func_mysqli_fetch_all($link, $engine, "YEAR", @date('Y'), @date('Y'), 510); -func_mysqli_fetch_all($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520); +func_mysqli_fetch_all($link, $engine, "YEAR", $year, $year, 510); +func_mysqli_fetch_all($link, $engine, "YEAR NOT NULL", $year, $year, 520); func_mysqli_fetch_all($link, $engine, "YEAR", NULL, NULL, 530); $string255 = func_mysqli_fetch_array_make_string(255); diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 6e53b987d6761..459449d85f23c 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -3815,9 +3815,13 @@ static bool preload_try_resolve_constants(zend_class_entry *ce) bool resolved = true; for (i = 0; i < ce->default_properties_count; i++) { - val = &ce->default_properties_table[i]; + zend_property_info *prop = ce->properties_info_table[i]; + if (!prop) { + continue; + } + + val = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop->offset)]; if (Z_TYPE_P(val) == IS_CONSTANT_AST) { - zend_property_info *prop = ce->properties_info_table[i]; if (UNEXPECTED(zval_update_constant_ex(val, prop->ce) != SUCCESS)) { resolved = ok = false; } @@ -4733,6 +4737,11 @@ static zend_result accel_finish_startup_preload(bool in_child) EG(class_table) = NULL; EG(function_table) = NULL; PG(report_memleaks) = orig_report_memleaks; +#ifdef ZTS + /* Reset the virtual CWD state back to the original state created by virtual_cwd_startup(). + * This is necessary because the normal startup code assumes the CWD state is active. */ + virtual_cwd_activate(); +#endif } else { zend_shared_alloc_unlock(); ret = FAILURE; diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index a6bb7c993c51b..d9f7e3d0f7836 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -1294,69 +1294,65 @@ void ir_build_def_use_lists(ir_ctx *ctx) void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref) { - ir_ref j, n, *p, *q, use; + ir_ref n, *p, *q, use; ir_use_list *use_list; - ir_ref skip = 0; IR_ASSERT(from > 0); use_list = &ctx->use_lists[from]; n = use_list->count; - for (j = 0, p = q = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { + for (p = q = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; - if (use == ref) { - skip++; - } else { + if (use != ref) { if (p != q) { *q = use; } q++; } } - if (skip) { - use_list->count -= skip; + if (p != q) { + use_list->count -= (p - q); do { *q = IR_UNUSED; q++; - } while (--skip); + } while (q != p); } } void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref) { - ir_ref j, n, *p; + ir_ref n, *p; ir_use_list *use_list; IR_ASSERT(from > 0); use_list = &ctx->use_lists[from]; n = use_list->count; - j = 0; p = &ctx->use_edges[use_list->refs]; - while (j < n) { + while (n > 0) { if (*p == ref) { use_list->count--; - j++; - while (j < n) { + n--; + while (n > 0) { *p = *(p+1); p++; - j++; + n--; } *p = IR_UNUSED; break; } p++; - j++; + n--; } } void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use) { ir_use_list *use_list; - ir_ref i, n, *p; + ir_ref n, *p; IR_ASSERT(ref > 0); use_list = &ctx->use_lists[ref]; n = use_list->count; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == use) { *p = new_use; break; @@ -1367,12 +1363,12 @@ void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use) { ir_use_list *use_list; - ir_ref i, n, *p; + ir_ref n, *p; IR_ASSERT(ref > 0); use_list = &ctx->use_lists[ref]; n = use_list->count; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == use) { *p = new_use; } @@ -2417,10 +2413,18 @@ static ir_ref _ir_fold_condition(ir_ctx *ctx, ir_ref ref) if (IR_IS_TYPE_INT(op2_insn->type) && op2_insn->val.u64 == 0) { ref = insn->op1; insn = &ctx->ir_base[ref]; + if (insn->op == IR_ALLOCA || insn->op == IR_VADDR) { + return IR_TRUE; + } } } else if (insn->op == IR_EQ && insn->op2 == IR_TRUE) { ref = insn->op1; insn = &ctx->ir_base[ref]; + } else if (insn->op == IR_EQ && insn->op2 == IR_NULL) { + ir_insn *op1_insn = &ctx->ir_base[insn->op1]; + if (op1_insn->op == IR_ALLOCA || op1_insn->op == IR_VADDR) { + return IR_FALSE; + } } // while (insn->op == IR_SEXT || insn->op == IR_ZEXT || insn->op == IR_BITCAST) { // ref = insn->op1; diff --git a/ext/opcache/jit/ir/ir_cfg.c b/ext/opcache/jit/ir/ir_cfg.c index 3678867e46c7a..16facae51b1f6 100644 --- a/ext/opcache/jit/ir/ir_cfg.c +++ b/ext/opcache/jit/ir/ir_cfg.c @@ -328,7 +328,7 @@ static void ir_remove_predecessor(ir_ctx *ctx, ir_block *bb, uint32_t from) static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) { - ir_ref i, j, n, k, *p, use; + ir_ref i, j, n, k, *p, *q, use; ir_insn *use_insn; ir_use_list *use_list; ir_bitset life_inputs; @@ -359,7 +359,7 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) use_list = &ctx->use_lists[merge]; if (use_list->count > 1) { n++; - for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { + for (k = use_list->count, p = q = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { use = *p; use_insn = &ctx->ir_base[use]; if (use_insn->op == IR_PHI) { @@ -379,8 +379,22 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) for (j = 2; j <= n; j++) { ir_insn_set_op(use_insn, j, IR_UNUSED); } - ir_use_list_remove_all(ctx, merge, use); + continue; + } + + /*compact use list */ + if (p != q){ + *q = use; } + q++; + } + + if (p != q) { + use_list->count -= (p - q); + do { + *q = IR_UNUSED; /* clenu-op the removed tail */ + q++; + } while (p != q); } } } else { @@ -389,7 +403,7 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) use_list = &ctx->use_lists[merge]; if (use_list->count > 1) { n++; - for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { + for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { use = *p; use_insn = &ctx->ir_base[use]; if (use_insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c index 40a475ae22f99..f12b4776fa1e0 100644 --- a/ext/opcache/jit/ir/ir_check.c +++ b/ext/opcache/jit/ir/ir_check.c @@ -42,11 +42,11 @@ void ir_consistency_check(void) static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to) { - ir_ref n, j, *p; + ir_ref n, *p; ir_use_list *use_list = &ctx->use_lists[from]; n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == to) { return 1; } @@ -304,9 +304,9 @@ bool ir_check(const ir_ctx *ctx) if (ctx->use_lists) { ir_use_list *use_list = &ctx->use_lists[i]; - ir_ref count; + ir_ref count, n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < use_list->count; j++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; if (!ir_check_input_list(ctx, i, use)) { fprintf(stderr, "ir_base[%d] is in use list of ir_base[%d]\n", use, i); @@ -347,8 +347,8 @@ bool ir_check(const ir_ctx *ctx) break; default: /* skip data references */ - count = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < use_list->count; j++, p++) { + count = n = use_list->count; + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; if (!(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_CONTROL)) { count--; diff --git a/ext/opcache/jit/ir/ir_dump.c b/ext/opcache/jit/ir/ir_dump.c index f9b26c4d2a12a..54fddf50ac066 100644 --- a/ext/opcache/jit/ir/ir_dump.c +++ b/ext/opcache/jit/ir/ir_dump.c @@ -177,7 +177,7 @@ static void ir_dump_dessa_moves(const ir_ctx *ctx, int b, ir_block *bb, FILE *f) use_list = &ctx->use_lists[succ_bb->start]; k = ir_phi_input_number(ctx, succ_bb, b); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use_ref = *p; use_insn = &ctx->ir_base[use_ref]; if (use_insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c index 367dee72963bf..5cf44a51d0f48 100644 --- a/ext/opcache/jit/ir/ir_emit.c +++ b/ext/opcache/jit/ir/ir_emit.c @@ -161,7 +161,7 @@ static ir_reg ir_get_param_reg(const ir_ctx *ctx, ir_ref ref) } #endif - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PARAM) { @@ -917,7 +917,7 @@ static void ir_emit_dessa_moves(ir_ctx *ctx, int b, ir_block *bb) copies = alloca(use_list->count * sizeof(ir_dessa_copy)); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { ir_ref ref = *p; ir_insn *insn = &ctx->ir_base[ref]; diff --git a/ext/opcache/jit/ir/ir_fold.h b/ext/opcache/jit/ir/ir_fold.h index 6f0bfea47820d..c7745a8c68723 100644 --- a/ext/opcache/jit/ir/ir_fold.h +++ b/ext/opcache/jit/ir/ir_fold.h @@ -1464,7 +1464,9 @@ IR_FOLD(EQ(SEXT, C_I32)) IR_FOLD(EQ(SEXT, C_I64)) IR_FOLD(EQ(SEXT, C_ADDR)) { - if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { + if (ctx->use_lists && ctx->use_lists[op1_insn->op1].count != 1) { + /* pass */ + } else if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { opt = IR_OPT(IR_NOT, IR_BOOL); op1 = op1_insn->op1; op2 = IR_UNUSED; @@ -1509,7 +1511,9 @@ IR_FOLD(NE(SEXT, C_I32)) IR_FOLD(NE(SEXT, C_I64)) IR_FOLD(NE(SEXT, C_ADDR)) { - if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { + if (ctx->use_lists && ctx->use_lists[op1_insn->op1].count != 1) { + /* pass */ + } else if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { IR_FOLD_COPY(op1_insn->op1); } else { ir_type type = ctx->ir_base[op1_insn->op1].type; @@ -2464,6 +2468,17 @@ IR_FOLD(SEXT(AND)) IR_FOLD_NEXT; } +IR_FOLD(SEXT(SHR)) +{ + if (IR_IS_CONST_REF(op1_insn->op2) + && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op) + && ctx->ir_base[op1_insn->op2].val.u64 != 0) { + opt = IR_OPT(IR_ZEXT, IR_OPT_TYPE(opt)); + IR_FOLD_RESTART; + } + IR_FOLD_NEXT; +} + IR_FOLD(TRUNC(AND)) { if (IR_IS_CONST_REF(op1_insn->op2)) { @@ -2490,6 +2505,44 @@ IR_FOLD(TRUNC(AND)) IR_FOLD_NEXT; } +IR_FOLD(AND(ZEXT, C_I16)) +IR_FOLD(AND(ZEXT, C_U16)) +IR_FOLD(AND(ZEXT, C_I32)) +IR_FOLD(AND(ZEXT, C_U32)) +IR_FOLD(AND(ZEXT, C_I64)) +IR_FOLD(AND(ZEXT, C_U64)) +IR_FOLD(AND(ZEXT, C_ADDR)) +{ + ir_type src_size = ir_type_size[ctx->ir_base[op1_insn->op1].type]; + + if ((src_size == 1 && op2_insn->val.u64 == 0xff) + || (src_size == 2 && op2_insn->val.u64 == 0xffff) + || (src_size == 4 && op2_insn->val.u64 == 0xffffffff)) { + IR_FOLD_COPY(op1); + } + IR_FOLD_NEXT; +} + +IR_FOLD(AND(SEXT, C_I16)) +IR_FOLD(AND(SEXT, C_U16)) +IR_FOLD(AND(SEXT, C_I32)) +IR_FOLD(AND(SEXT, C_U32)) +IR_FOLD(AND(SEXT, C_I64)) +IR_FOLD(AND(SEXT, C_U64)) +IR_FOLD(AND(SEXT, C_ADDR)) +{ + ir_type src_size = ir_type_size[ctx->ir_base[op1_insn->op1].type]; + + if ((src_size == 1 && op2_insn->val.u64 == 0xff) + || (src_size == 2 && op2_insn->val.u64 == 0xffff) + || (src_size == 4 && op2_insn->val.u64 == 0xffffffff)) { + opt = IR_OPT(IR_ZEXT, IR_OPT_TYPE(opt)); + op1 = op1_insn->op1; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } + IR_FOLD_NEXT; +} IR_FOLD(AND(SHR, C_I8)) IR_FOLD(AND(SHR, C_U8)) { diff --git a/ext/opcache/jit/ir/ir_gcm.c b/ext/opcache/jit/ir/ir_gcm.c index be8744ef198fd..8bd6be5d10aa0 100644 --- a/ext/opcache/jit/ir/ir_gcm.c +++ b/ext/opcache/jit/ir/ir_gcm.c @@ -401,9 +401,10 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) for (i = 1; i < clones_count; i++) { clones[i].ref = clone = ir_emit(ctx, insn->optx, insn->op1, insn->op2, insn->op3); insn = &ctx->ir_base[ref]; - if (insn->op1 > 0) ir_use_list_add(ctx, insn->op1, clone); - if (insn->op2 > 0) ir_use_list_add(ctx, insn->op2, clone); - if (insn->op3 > 0) ir_use_list_add(ctx, insn->op3, clone); + /* Depending on the flags in IR_OPS, these can be references or data. */ + if (insn->op1 > 0 && insn->inputs_count >= 1) ir_use_list_add(ctx, insn->op1, clone); + if (insn->op2 > 0 && insn->inputs_count >= 2) ir_use_list_add(ctx, insn->op2, clone); + if (insn->op3 > 0 && insn->inputs_count >= 3) ir_use_list_add(ctx, insn->op3, clone); } /* Reconstruct IR: Update DEF->USE lists, CFG mapping and etc */ @@ -412,10 +413,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) n = ctx->use_lists[ref].refs; for (i = 0; i < clones_count; i++) { clone = clones[i].ref; - if (clones[i].use_count == 1) { + if (clones[i].use_count == 1 + && ctx->cfg_blocks[clones[i].block].loop_depth >= ctx->cfg_blocks[uses[clones[i].use].block].loop_depth) { /* TOTALLY_USEFUL block may be a head of a diamond above the real usage. * Sink it down to the real usage block. - * Clones with few uses we be sunk into the LCA block. + * Clones with few uses will be sunk into the LCA block. */ clones[i].block = uses[clones[i].use].block; } diff --git a/ext/opcache/jit/ir/ir_ra.c b/ext/opcache/jit/ir/ir_ra.c index dcc67e0074fa4..0c0e8dec3b47a 100644 --- a/ext/opcache/jit/ir/ir_ra.c +++ b/ext/opcache/jit/ir/ir_ra.c @@ -1901,7 +1901,6 @@ int ir_coalesce(ir_ctx *ctx) qsort(list, count, sizeof(ir_coalesce_block), ir_block_cmp); while (count > 0) { - uint32_t i; count--; b = list[count].b; @@ -1913,7 +1912,7 @@ int ir_coalesce(ir_ctx *ctx) k = ir_phi_input_number(ctx, succ_bb, b); use_list = &ctx->use_lists[succ_bb->start]; n = use_list->count; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PHI) { @@ -2061,7 +2060,7 @@ int ir_coalesce(ir_ctx *ctx) int ir_compute_dessa_moves(ir_ctx *ctx) { - uint32_t b, i, n; + uint32_t b, n; ir_ref j, k, *p, use; ir_block *bb; ir_use_list *use_list; @@ -2076,7 +2075,7 @@ int ir_compute_dessa_moves(ir_ctx *ctx) if (n > 1) { IR_ASSERT(k == ctx->ir_base[bb->start].inputs_count); k++; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PHI) { @@ -2136,7 +2135,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) len = ir_bitset_len(ctx->vregs_count + 1); todo = ir_bitset_malloc(ctx->vregs_count + 1); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { ref = *p; insn = &ctx->ir_base[ref]; if (insn->op == IR_PHI) { @@ -2205,7 +2204,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) ir_mem_free(loc); if (have_constants_or_addresses) { - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { ref = *p; insn = &ctx->ir_base[ref]; if (insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_save.c b/ext/opcache/jit/ir/ir_save.c index be9b142c8f324..b12cc267af607 100644 --- a/ext/opcache/jit/ir/ir_save.c +++ b/ext/opcache/jit/ir/ir_save.c @@ -53,7 +53,7 @@ static void ir_save_dessa_moves(const ir_ctx *ctx, int b, ir_block *bb, FILE *f) use_list = &ctx->use_lists[succ_bb->start]; k = ir_phi_input_number(ctx, succ_bb, b); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use_ref = *p; use_insn = &ctx->ir_base[use_ref]; if (use_insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_sccp.c b/ext/opcache/jit/ir/ir_sccp.c index 18192d7f1792a..af039aaef829b 100644 --- a/ext/opcache/jit/ir/ir_sccp.c +++ b/ext/opcache/jit/ir/ir_sccp.c @@ -553,8 +553,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } if (!may_benefit) { IR_MAKE_BOTTOM_EX(i); - if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC - || insn->op == IR_ZEXT || insn->op == IR_SEXT || insn->op == IR_EQ || insn->op == IR_NE) { + if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC) { ir_bitqueue_add(iter_worklist, i); } } else if (!ir_sccp_fold(ctx, _values, worklist, i, insn)) { @@ -562,8 +561,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi continue; } else if (_values[i].op == IR_BOTTOM) { insn = &ctx->ir_base[i]; - if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC - || insn->op == IR_ZEXT || insn->op == IR_SEXT || insn->op == IR_EQ || insn->op == IR_NE) { + if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC) { ir_bitqueue_add(iter_worklist, i); } } @@ -571,7 +569,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi IR_MAKE_BOTTOM_EX(i); } } else if (flags & IR_OP_FLAG_BB_START) { - if (insn->op == IR_MERGE || insn->op == IR_BEGIN) { + if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_BEGIN) { ir_bitqueue_add(iter_worklist, i); } if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) { @@ -667,7 +665,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi use_list = &ctx->use_lists[i]; n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; IR_ASSERT(use > 0); use_insn = &ctx->ir_base[use]; @@ -919,163 +917,128 @@ static void ir_sccp_remove_if(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref } } -static void ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref unfeasible_inputs) +static bool ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist) { - ir_ref i, j, n, k, *p, use; - ir_insn *insn, *use_insn; + ir_ref old_merge_inputs, new_merge_inputs, i, *p; ir_use_list *use_list; ir_bitset life_inputs; + ir_bitset_base_t holder = 0; - insn = &ctx->ir_base[ref]; IR_ASSERT(insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN); - n = insn->inputs_count; - if (n - unfeasible_inputs == 1) { - /* remove MERGE completely */ - for (j = 1; j <= n; j++) { - ir_ref input = ir_insn_op(insn, j); - if (input && IR_IS_REACHABLE(input)) { - ir_insn *input_insn = &ctx->ir_base[input]; - - IR_ASSERT(input_insn->op == IR_END || input_insn->op == IR_LOOP_END|| - input_insn->op == IR_IJMP || input_insn->op == IR_UNREACHABLE); - if (input_insn->op == IR_END || input_insn->op == IR_LOOP_END) { - ir_ref prev, next = IR_UNUSED; - ir_insn *next_insn = NULL; - - prev = input_insn->op1; - use_list = &ctx->use_lists[ref]; - if (use_list->count == 1) { - next = ctx->use_edges[use_list->refs]; - next_insn = &ctx->ir_base[next]; - } else { - k = 0; - p = &ctx->use_edges[use_list->refs]; - while (k < use_list->count) { - use = *p; - use_insn = &ctx->ir_base[use]; -#if IR_COMBO_COPY_PROPAGATION - IR_ASSERT((use_insn->op != IR_PHI) && "PHI must be already removed"); -#else - if (use_insn->op == IR_PHI) { - /* Convert PHI into COPY */ - ir_ref i, n = use_insn->inputs_count; - - for (i = 2; i <= n; i++) { - if (i != j + 1) { - ir_ref from = ir_insn_op(use_insn, i); - if (from > 0) { - ir_use_list_remove_one(ctx, from, use); - } - ir_insn_set_op(use_insn, i, IR_UNUSED); - } - } - use_insn->optx = IR_OPTX(IR_COPY, use_insn->type, 1); - use_insn->op1 = ir_insn_op(use_insn, j + 1); - ir_insn_set_op(use_insn, j + 1, IR_UNUSED); - ir_use_list_remove_one(ctx, ref, use); - p = &ctx->use_edges[use_list->refs + k]; - continue; - } -#endif - if (ir_op_flags[use_insn->op] & IR_OP_FLAG_CONTROL) { - IR_ASSERT(!next); - next = use; - next_insn = use_insn; - } else if (use_insn->op != IR_NOP) { - IR_ASSERT(use_insn->op1 == ref); - IR_ASSERT(use_insn->op == IR_VAR); - ir_ref region = prev; - while (!IR_IS_BB_START(ctx->ir_base[region].op)) { - region = ctx->ir_base[region].op1; - } - use_insn->op1 = region; - ir_use_list_add(ctx, region, use); - p = &ctx->use_edges[use_list->refs + k]; - } - k++; - p++; - } - } - IR_ASSERT(prev && next); - if (prev < next) { - /* remove MERGE and input END from double linked control list */ - next_insn->op1 = prev; - ir_use_list_replace_one(ctx, prev, input, next); - /* remove MERGE and input END instructions */ - ir_sccp_make_nop(ctx, ref); - ir_sccp_make_nop(ctx, input); - } else { - for (i = 2; i <= n; i++) { - ir_insn_set_op(insn, i, IR_UNUSED); - } - insn->op = IR_BEGIN; - insn->op1 = input; - input_insn->op = IR_END; - } - break; - } else { - for (i = 2; i <= n; i++) { - ir_insn_set_op(insn, i, IR_UNUSED); - } - insn->op = IR_BEGIN; - insn->op1 = input; - } + old_merge_inputs = insn->inputs_count; + new_merge_inputs = 0; + life_inputs = (old_merge_inputs < IR_BITSET_BITS) ? &holder : ir_bitset_malloc(old_merge_inputs + 1); + + for (i = 1; i <= old_merge_inputs; i++) { + ir_ref input = ir_insn_op(insn, i); + + if (input) { + new_merge_inputs++; + if (new_merge_inputs != i) { + ir_insn_set_op(insn, new_merge_inputs, input); } + ir_bitset_incl(life_inputs, i); } - } else { - n = insn->inputs_count; - i = 1; - life_inputs = ir_bitset_malloc(n + 1); - for (j = 1; j <= n; j++) { - ir_ref input = ir_insn_op(insn, j); + } - if (input) { - if (i != j) { - ir_insn_set_op(insn, i, input); - } - ir_bitset_incl(life_inputs, j); - i++; - } + if (new_merge_inputs == old_merge_inputs) { + /* All inputs are feasible */ + if (life_inputs != &holder) { + ir_mem_free(life_inputs); } - j = i; - while (j <= n) { - ir_insn_set_op(insn, j, IR_UNUSED); - j++; + return 0; + } + + for (i = new_merge_inputs + 1; i <= old_merge_inputs; i++) { + ir_insn_set_op(insn, i, IR_UNUSED); + } + + if (new_merge_inputs <= 1) { +#if 0 + if (new_merge_inputs == 1 + && insn->op == IR_LOOP_BEGIN + && insn->op1 > ref) { // TODO: check dominance instead of order + /* dead loop */ + ir_use_list_remove_one(ctx, insn->op1, ref); + insn->op1 = IR_UNUSED; + new_merge_inputs = 0; } - i--; - insn->inputs_count = i; +#endif + insn->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); + ir_bitqueue_add(worklist, ref); + } else { + insn->inputs_count = new_merge_inputs; + } - n++; - use_list = &ctx->use_lists[ref]; - if (use_list->count > 1) { - for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { - use = *p; - use_insn = &ctx->ir_base[use]; - if (use_insn->op == IR_PHI) { - i = 2; - for (j = 2; j <= n; j++) { - ir_ref input = ir_insn_op(use_insn, j); - - if (ir_bitset_in(life_inputs, j - 1)) { - IR_ASSERT(input); - if (i != j) { - ir_insn_set_op(use_insn, i, input); - } - i++; - } else if (!IR_IS_CONST_REF(input)) { - ir_use_list_remove_one(ctx, input, use); + /* Update PHIs */ + use_list = &ctx->use_lists[ref]; + if (use_list->count > 1) { + ir_ref use_count = 0; + ir_ref *q; + + for (i = 0, p = q = &ctx->use_edges[use_list->refs]; i < use_list->count; p++, i++) { + ir_ref use = *p; + ir_insn *use_insn = &ctx->ir_base[use]; + + if (use_insn->op == IR_PHI) { + ir_ref j, k; + + /* compress PHI */ + for (j = k = 1; j <= old_merge_inputs; j++) { + ir_ref input = ir_insn_op(use_insn, j + 1); + + if (ir_bitset_in(life_inputs, j)) { + IR_ASSERT(input); + if (k != j) { + ir_insn_set_op(use_insn, k + 1, input); } + k++; + } else if (input > 0) { + ir_use_list_remove_one(ctx, input, use); } - while (i <= n) { - ir_insn_set_op(use_insn, i, IR_UNUSED); - i++; - } - use_insn->inputs_count = insn->inputs_count + 1; } + while (k <= old_merge_inputs) { + k++; + ir_insn_set_op(use_insn, k, IR_UNUSED); + } + + if (new_merge_inputs == 0) { + /* remove PHI */ +#if 0 + use_insn->op1 = IR_UNUSED; + ir_iter_remove_insn(ctx, use, worklist); +#else + IR_ASSERT(0); +#endif + continue; + } else if (new_merge_inputs == 1) { + /* replace PHI by COPY */ + use_insn->optx = IR_OPTX(IR_COPY, use_insn->type, 1); + use_insn->op1 = use_insn->op2; + use_insn->op2 = IR_UNUSED; + ir_bitqueue_add(worklist, use); + continue; + } else { + use_insn->inputs_count = new_merge_inputs + 1; + } + } + if (p != q) { + *q = use; } + q++; + use_count++; } + for (i = use_count; i < use_list->count; q++, i++) { + *q = IR_UNUSED; + } + use_list->count = use_count; + } + + if (life_inputs != &holder) { ir_mem_free(life_inputs); } + + return 1; } static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_bitqueue *iter_worklist) @@ -1105,7 +1068,7 @@ static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_ if (insn->op == IR_NOP) { /* already removed */ } else if (ir_op_flags[insn->op] & (IR_OP_FLAG_DATA|IR_OP_FLAG_MEM)) { - if (insn->op != IR_PARAM && (insn->op != IR_VAR || _values[insn->op1].op == IR_TOP)) { + if (insn->op != IR_PARAM) { ir_sccp_remove_insn(ctx, _values, i, iter_worklist); } } else { @@ -1137,7 +1100,7 @@ static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_ while ((i = ir_bitqueue_pop(worklist)) >= 0) { IR_ASSERT(_values[i].op == IR_MERGE); - ir_sccp_remove_unfeasible_merge_inputs(ctx, _values, i, _values[i].op1); + ir_sccp_remove_unfeasible_merge_inputs(ctx, i, &ctx->ir_base[i], iter_worklist); } } @@ -1261,7 +1224,7 @@ static void ir_iter_replace_insn(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bit ir_bitqueue_add(worklist, input); } else if (ctx->ir_base[input].op == IR_PHI && ctx->use_lists[input].count == 1) { /* try to optimize PHI into ABS/MIN/MAX/COND */ - ir_bitqueue_add(worklist, input); + ir_bitqueue_add(worklist, ctx->ir_base[input].op1); } } } @@ -1690,9 +1653,10 @@ static ir_ref ir_promote_f2d(ir_ctx *ctx, ir_ref ref, ir_ref use) return ref; } -static bool ir_may_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref) +static bool ir_may_promote_trunc(ir_ctx *ctx, ir_type type, ir_ref ref) { ir_insn *insn = &ctx->ir_base[ref]; + ir_ref *p, n, input; if (IR_IS_CONST_REF(ref)) { return !IR_IS_SYM_CONST(insn->op); @@ -1700,24 +1664,58 @@ static bool ir_may_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref) switch (insn->op) { case IR_ZEXT: case IR_SEXT: - return ctx->ir_base[insn->op1].type == type; + case IR_TRUNC: + return ctx->ir_base[insn->op1].type == type || ctx->use_lists[ref].count == 1; case IR_NEG: case IR_ABS: case IR_NOT: return ctx->use_lists[ref].count == 1 && - ir_may_promote_i2i(ctx, type, insn->op1); + ir_may_promote_trunc(ctx, type, insn->op1); case IR_ADD: case IR_SUB: case IR_MUL: -// case IR_DIV: case IR_MIN: case IR_MAX: case IR_OR: case IR_AND: case IR_XOR: + case IR_SHL: return ctx->use_lists[ref].count == 1 && - ir_may_promote_i2i(ctx, type, insn->op1) && - ir_may_promote_i2i(ctx, type, insn->op2); + ir_may_promote_trunc(ctx, type, insn->op1) && + ir_may_promote_trunc(ctx, type, insn->op2); +// case IR_SHR: +// case IR_SAR: +// case IR_DIV: +// case IR_MOD: +// case IR_FP2INT: +// TODO: ??? + case IR_COND: + return ctx->use_lists[ref].count == 1 && + ir_may_promote_trunc(ctx, type, insn->op2) && + ir_may_promote_trunc(ctx, type, insn->op3); + case IR_PHI: + if (ctx->use_lists[ref].count != 1) { + ir_use_list *use_list = &ctx->use_lists[ref]; + ir_ref count = 0; + + for (p = &ctx->use_edges[use_list->refs], n = use_list->count; n > 0; p++, n--) { + if (*p != ref) { + if (count) { + return 0; + } + count = 1; + } + } + } + for (p = insn->ops + 1, n = insn->inputs_count - 1; n > 0; p++, n--) { + input = *p; + if (input != ref) { + if (!ir_may_promote_trunc(ctx, type, input)) { + return 0; + } + } + } + return 1; default: break; } @@ -1729,6 +1727,7 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use) { ir_insn *insn = &ctx->ir_base[ref]; uint32_t count; + ir_ref *p, n, input; if (IR_IS_CONST_REF(ref)) { return ir_const(ctx, insn->val, type); @@ -1736,6 +1735,22 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use) switch (insn->op) { case IR_ZEXT: case IR_SEXT: + case IR_TRUNC: + if (ctx->ir_base[insn->op1].type != type) { + ir_type src_type = ctx->ir_base[insn->op1].type; + if (ir_type_size[src_type] == ir_type_size[type]) { + insn->op = IR_BITCAST; + } else if (ir_type_size[src_type] > ir_type_size[type]) { + insn->op = IR_TRUNC; + } else { + if (insn->op != IR_SEXT && insn->op != IR_ZEXT) { + insn->op = IR_IS_TYPE_SIGNED(type) ? IR_SEXT : IR_ZEXT; + } + } + insn->type = type; + return ref; + } + count = ctx->use_lists[ref].count; ir_use_list_remove_all(ctx, ref, use); if (ctx->use_lists[ref].count == 0) { @@ -1767,12 +1782,12 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use) case IR_ADD: case IR_SUB: case IR_MUL: -// case IR_DIV: case IR_MIN: case IR_MAX: case IR_OR: case IR_AND: case IR_XOR: + case IR_SHL: if (insn->op1 == insn->op2) { insn->op2 = insn->op1 = ir_promote_i2i(ctx, type, insn->op1, ref); } else { @@ -1781,6 +1796,30 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use) } insn->type = type; return ref; +// case IR_DIV: +// case IR_MOD: +// case IR_SHR: +// case IR_SAR: +// case IR_FP2INT: +// TODO: ??? + case IR_COND: + if (insn->op2 == insn->op3) { + insn->op3 = insn->op2 = ir_promote_i2i(ctx, type, insn->op2, ref); + } else { + insn->op2 = ir_promote_i2i(ctx, type, insn->op2, ref); + insn->op3 = ir_promote_i2i(ctx, type, insn->op3, ref); + } + insn->type = type; + return ref; + case IR_PHI: + for (p = insn->ops + 1, n = insn->inputs_count - 1; n > 0; p++, n--) { + input = *p; + if (input != ref) { + *p = ir_promote_i2i(ctx, type, input, ref); + } + } + insn->type = type; + return ref; default: break; } @@ -1852,58 +1891,163 @@ static ir_ref ir_ext_ref(ir_ctx *ctx, ir_ref var_ref, ir_ref src_ref, ir_op op, return ref; } -static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bitqueue *worklist) +static uint32_t _ir_estimated_control(ir_ctx *ctx, ir_ref val) { - ir_type type = insn->type; - ir_op op = insn->op; - ir_ref ref = insn->op1; - ir_insn *phi_insn = &ctx->ir_base[ref]; - ir_insn *op_insn; - ir_use_list *use_list; - ir_ref n, *p, use, op_ref; + ir_insn *insn; + ir_ref n, *p, input, result, ctrl; - /* Check for simple induction variable in the form: x2 = PHI(loop, x1, x3); x3 = ADD(x2, _); */ - if (phi_insn->op != IR_PHI - || phi_insn->inputs_count != 3 /* (2 values) */ - || ctx->ir_base[phi_insn->op1].op != IR_LOOP_BEGIN) { - return 0; + if (IR_IS_CONST_REF(val)) { + return 1; /* IR_START */ } - op_ref = phi_insn->op3; - op_insn = &ctx->ir_base[op_ref]; - if ((op_insn->op != IR_ADD && op_insn->op != IR_SUB && op_insn->op != IR_MUL) - || (op_insn->op1 != ref && op_insn->op2 != ref) - || ctx->use_lists[op_ref].count != 1) { - return 0; + insn = &ctx->ir_base[val]; + if (ir_op_flags[insn->op] & (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM)) { + return val; } - /* Check if we may change the type of the induction variable */ - use_list = &ctx->use_lists[ref]; - n = use_list->count; - for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { - use = *p; - if (use == op_ref || use == ext_ref) { - continue; + IR_ASSERT(ir_op_flags[insn->op] & IR_OP_FLAG_DATA); + if (IR_OPND_KIND(ir_op_flags[insn->op], 1) & IR_OPND_CONTROL_DEP) { + return insn->op1; + } + + n = insn->inputs_count; + p = insn->ops + 1; + + result = 1; + for (; n > 0; p++, n--) { + input = *p; + ctrl = _ir_estimated_control(ctx, input); + if (ctrl > result) { // TODO: check dominance depth instead of order + result = ctrl; + } + } + return result; +} + +static bool ir_is_loop_invariant(ir_ctx *ctx, ir_ref ref, ir_ref loop) +{ + ref = _ir_estimated_control(ctx, ref); + return ref < loop; // TODO: check dominance instead of order +} + +static bool ir_is_cheaper_ext(ir_ctx *ctx, ir_ref ref, ir_ref loop, ir_ref ext_ref, ir_op op) +{ + if (IR_IS_CONST_REF(ref)) { + return 1; + } else { + ir_insn *insn = &ctx->ir_base[ref]; + + if (insn->op == IR_LOAD) { + if (ir_is_loop_invariant(ctx, ref, loop)) { + return 1; + } else { + /* ZEXT(LOAD(_, _)) costs the same as LOAD(_, _) */ + if (ctx->use_lists[ref].count == 2) { + return 1; + } else if (ctx->use_lists[ref].count == 3) { + ir_use_list *use_list = &ctx->use_lists[ref]; + ir_ref *p, n, use; + + for (p = &ctx->use_edges[use_list->refs], n = use_list->count; n > 0; p++, n--) { + use = *p; + if (use != ext_ref) { + ir_insn *use_insn = &ctx->ir_base[use]; + + if (use_insn->op != op + && (!(ir_op_flags[use_insn->op] & (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM)) + || use_insn->op1 != ref)) { + return 0; + } + } + } + return 1; + } + } + return 0; } else { - ir_insn *use_insn = &ctx->ir_base[use]; + return ir_is_loop_invariant(ctx, ref, loop); + } + } +} - if ((use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) - && (use_insn->op1 == ref || use_insn->op2 == ref)) { - continue; - } else if (use_insn->op == IR_IF) { +static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref phi_ref, ir_ref op_ref, ir_bitqueue *worklist) +{ + ir_op op = ctx->ir_base[ext_ref].op; + ir_type type = ctx->ir_base[ext_ref].type; + ir_insn *phi_insn; + ir_use_list *use_list; + ir_ref n, *p, use, ext_ref_2 = IR_UNUSED; + + /* Check if we may change the type of the induction variable */ + use_list = &ctx->use_lists[phi_ref]; + n = use_list->count; + if (n > 1) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { + use = *p; + if (use == op_ref || use == ext_ref) { continue; } else { - return 0; + ir_insn *use_insn = &ctx->ir_base[use]; + + if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) { + if (use_insn->op1 == phi_ref) { + if (ir_is_cheaper_ext(ctx, use_insn->op2, ctx->ir_base[phi_ref].op1, ext_ref, op)) { + continue; + } + } else if (use_insn->op2 == phi_ref) { + if (ir_is_cheaper_ext(ctx, use_insn->op1, ctx->ir_base[phi_ref].op1, ext_ref, op)) { + continue; + } + } + return 0; + } else if (use_insn->op == IR_IF) { + continue; + } else if (!ext_ref_2 && use_insn->op == op && use_insn->type == type) { + ext_ref_2 = use; + continue; + } else { + return 0; + } } } } - phi_insn->type = insn->type; - op_insn->type = insn->type; + use_list = &ctx->use_lists[op_ref]; + n = use_list->count; + if (n > 1) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { + use = *p; + if (use == phi_ref || use == ext_ref) { + continue; + } else { + ir_insn *use_insn = &ctx->ir_base[use]; + + if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) { + if (use_insn->op1 == phi_ref) { + if (ir_is_cheaper_ext(ctx, use_insn->op2, ctx->ir_base[phi_ref].op1, ext_ref, op)) { + continue; + } + } else if (use_insn->op2 == phi_ref) { + if (ir_is_cheaper_ext(ctx, use_insn->op1, ctx->ir_base[phi_ref].op1, ext_ref, op)) { + continue; + } + } + return 0; + } else if (use_insn->op == IR_IF) { + continue; + } else if (!ext_ref_2 && use_insn->op == op && use_insn->type == type) { + ext_ref_2 = use; + continue; + } else { + return 0; + } + } + } + } - for (n = 0; n < ctx->use_lists[ref].count; n++) { + for (n = 0; n < ctx->use_lists[phi_ref].count; n++) { /* "use_lists" may be reallocated by ir_ext_ref() */ - use = ctx->use_edges[ctx->use_lists[ref].refs + n]; + use = ctx->use_edges[ctx->use_lists[phi_ref].refs + n]; if (use == ext_ref) { continue; } else { @@ -1911,11 +2055,14 @@ static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bi if (use_insn->op == IR_IF) { continue; + } else if (use_insn->op == op) { + IR_ASSERT(ext_ref_2 == use); + continue; } IR_ASSERT(((use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) || use_insn->op == IR_ADD || use_insn->op == IR_SUB || use_insn->op == IR_MUL) - && (use_insn->op1 == ref || use_insn->op2 == ref)); - if (use_insn->op1 != ref) { + && (use_insn->op1 == phi_ref || use_insn->op2 == phi_ref)); + if (use_insn->op1 != phi_ref) { if (IR_IS_CONST_REF(use_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op1].op)) { ctx->ir_base[use].op1 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op1], op, type); @@ -1924,7 +2071,7 @@ static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bi } ir_bitqueue_add(worklist, use); } - if (use_insn->op2 != ref) { + if (use_insn->op2 != phi_ref) { if (IR_IS_CONST_REF(use_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op2].op)) { ctx->ir_base[use].op2 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op2], op, type); @@ -1936,19 +2083,108 @@ static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bi } } - ir_iter_replace_insn(ctx, ext_ref, ref, worklist); + if (ctx->use_lists[op_ref].count > 1) { + for (n = 0; n < ctx->use_lists[op_ref].count; n++) { + /* "use_lists" may be reallocated by ir_ext_ref() */ + use = ctx->use_edges[ctx->use_lists[op_ref].refs + n]; + if (use == ext_ref || use == phi_ref) { + continue; + } else { + ir_insn *use_insn = &ctx->ir_base[use]; + + if (use_insn->op == IR_IF) { + continue; + } else if (use_insn->op == op) { + IR_ASSERT(ext_ref_2 == use); + continue; + } + IR_ASSERT(use_insn->op >= IR_EQ && use_insn->op <= IR_UGT); + if (use_insn->op1 != op_ref) { + if (IR_IS_CONST_REF(use_insn->op1) + && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op1].op)) { + ctx->ir_base[use].op1 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op1], op, type); + } else { + ctx->ir_base[use].op1 = ir_ext_ref(ctx, use, use_insn->op1, op, type, worklist); + } + ir_bitqueue_add(worklist, use); + } + if (use_insn->op2 != op_ref) { + if (IR_IS_CONST_REF(use_insn->op2) + && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op2].op)) { + ctx->ir_base[use].op2 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op2], op, type); + } else { + ctx->ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op, type, worklist); + } + ir_bitqueue_add(worklist, use); + } + } + } + } + + ir_iter_replace_insn(ctx, ext_ref, ctx->ir_base[ext_ref].op1, worklist); + + if (ext_ref_2) { + ir_iter_replace_insn(ctx, ext_ref_2, ctx->ir_base[ext_ref_2].op1, worklist); + } + + ctx->ir_base[op_ref].type = type; - phi_insn = &ctx->ir_base[ref]; + phi_insn = &ctx->ir_base[phi_ref]; + phi_insn->type = type; if (IR_IS_CONST_REF(phi_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[phi_insn->op2].op)) { - ctx->ir_base[ref].op2 = ir_ext_const(ctx, &ctx->ir_base[phi_insn->op2], op, type); + ctx->ir_base[phi_ref].op2 = ir_ext_const(ctx, &ctx->ir_base[phi_insn->op2], op, type); } else { - ctx->ir_base[ref].op2 = ir_ext_ref(ctx, ref, phi_insn->op2, op, type, worklist); + ctx->ir_base[phi_ref].op2 = ir_ext_ref(ctx, phi_ref, phi_insn->op2, op, type, worklist); } return 1; } +static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bitqueue *worklist) + { + ir_ref ref = insn->op1; + + /* Check for simple induction variable in the form: x2 = PHI(loop, x1, x3); x3 = ADD(x2, _); */ + insn = &ctx->ir_base[ref]; + if (insn->op == IR_PHI + && insn->inputs_count == 3 /* (2 values) */ + && ctx->ir_base[insn->op1].op == IR_LOOP_BEGIN) { + ir_ref op_ref = insn->op3; + ir_insn *op_insn = &ctx->ir_base[op_ref]; + + if (op_insn->op == IR_ADD || op_insn->op == IR_SUB || op_insn->op == IR_MUL) { + if (op_insn->op1 == ref) { + if (ir_is_loop_invariant(ctx, op_insn->op2, insn->op1)) { + return ir_try_promote_induction_var_ext(ctx, ext_ref, ref, op_ref, worklist); + } + } else if (op_insn->op2 == ref) { + if (ir_is_loop_invariant(ctx, op_insn->op1, insn->op1)) { + return ir_try_promote_induction_var_ext(ctx, ext_ref, ref, op_ref, worklist); + } + } + } + } else if (insn->op == IR_ADD || insn->op == IR_SUB || insn->op == IR_MUL) { + if (!IR_IS_CONST_REF(insn->op1) + && ctx->ir_base[insn->op1].op == IR_PHI + && ctx->ir_base[insn->op1].inputs_count == 3 /* (2 values) */ + && ctx->ir_base[insn->op1].op3 == ref + && ctx->ir_base[ctx->ir_base[insn->op1].op1].op == IR_LOOP_BEGIN + && ir_is_loop_invariant(ctx, insn->op2, ctx->ir_base[insn->op1].op1)) { + return ir_try_promote_induction_var_ext(ctx, ext_ref, insn->op1, ref, worklist); + } else if (!IR_IS_CONST_REF(insn->op2) + && ctx->ir_base[insn->op2].op == IR_PHI + && ctx->ir_base[insn->op2].inputs_count == 3 /* (2 values) */ + && ctx->ir_base[insn->op2].op3 == ref + && ctx->ir_base[ctx->ir_base[insn->op2].op1].op == IR_LOOP_BEGIN + && ir_is_loop_invariant(ctx, insn->op1, ctx->ir_base[insn->op2].op1)) { + return ir_try_promote_induction_var_ext(ctx, ext_ref, insn->op2, ref, worklist); + } + } + + return 0; +} + static void ir_get_true_false_refs(const ir_ctx *ctx, ir_ref if_ref, ir_ref *if_true_ref, ir_ref *if_false_ref) { ir_use_list *use_list = &ctx->use_lists[if_ref]; @@ -1967,11 +2203,47 @@ static void ir_get_true_false_refs(const ir_ctx *ctx, ir_ref if_ref, ir_ref *if_ } } -static void ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin, ir_bitqueue *worklist2) +static void ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin, ir_bitqueue *worklist) { ir_ref prev, next; ir_use_list *use_list; + if (ctx->use_lists[begin].count > 1) { + ir_ref *p, n, i, use; + ir_insn *use_insn; + ir_ref region = end; + ir_ref next = IR_UNUSED; + + while (!IR_IS_BB_START(ctx->ir_base[region].op)) { + region = ctx->ir_base[region].op1; + } + + use_list = &ctx->use_lists[begin]; + n = use_list->count; + for (p = &ctx->use_edges[use_list->refs], i = 0; i < n; p++, i++) { + use = *p; + use_insn = &ctx->ir_base[use]; + if (ir_op_flags[use_insn->op] & IR_OP_FLAG_CONTROL) { + IR_ASSERT(!next); + next = use; + } else { + IR_ASSERT(use_insn->op == IR_VAR); + IR_ASSERT(use_insn->op1 == begin); + use_insn->op1 = region; + if (ir_use_list_add(ctx, region, use)) { + /* restore after reallocation */ + use_list = &ctx->use_lists[begin]; + n = use_list->count; + p = &ctx->use_edges[use_list->refs + i]; + } + } + } + + IR_ASSERT(next); + ctx->use_edges[use_list->refs] = next; + use_list->count = 1; + } + IR_ASSERT(ctx->ir_base[begin].op == IR_BEGIN); IR_ASSERT(ctx->ir_base[end].op == IR_END); IR_ASSERT(ctx->ir_base[begin].op1 == end); @@ -1992,7 +2264,7 @@ static void ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin, ir_bitqueue * ir_use_list_replace_one(ctx, prev, end, next); if (ctx->ir_base[prev].op == IR_BEGIN || ctx->ir_base[prev].op == IR_MERGE) { - ir_bitqueue_add(worklist2, prev); + ir_bitqueue_add(worklist, prev); } } @@ -2948,10 +3220,80 @@ static void ir_iter_optimize_merge(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge } } +static ir_ref ir_find_ext_use(ir_ctx *ctx, ir_ref ref) +{ + ir_use_list *use_list = &ctx->use_lists[ref]; + ir_ref *p, n, use; + ir_insn *use_insn; + + for (p = &ctx->use_edges[use_list->refs], n = use_list->count; n > 0; p++, n--) { + use = *p; + use_insn = &ctx->ir_base[use]; + if (use_insn->op == IR_SEXT || use_insn->op == IR_ZEXT) { + return use; + } + } + return IR_UNUSED; +} + +static void ir_iter_optimize_induction_var(ir_ctx *ctx, ir_ref phi_ref, ir_ref op_ref, ir_bitqueue *worklist) +{ + ir_ref ext_ref; + + ext_ref = ir_find_ext_use(ctx, phi_ref); + if (!ext_ref) { + ext_ref = ir_find_ext_use(ctx, op_ref); + } + if (ext_ref) { + ir_try_promote_induction_var_ext(ctx, ext_ref, phi_ref, op_ref, worklist); + } +} + +static void ir_iter_optimize_loop(ir_ctx *ctx, ir_ref loop_ref, ir_insn *loop, ir_bitqueue *worklist) +{ + ir_ref n; + + if (loop->inputs_count != 2 || ctx->use_lists[loop_ref].count <= 1) { + return; + } + + /* Check for simple induction variable in the form: x2 = PHI(loop, x1, x3); x3 = ADD(x2, _); */ + for (n = 0; n < ctx->use_lists[loop_ref].count; n++) { + /* "use_lists" may be reallocated by ir_ext_ref() */ + ir_ref use = ctx->use_edges[ctx->use_lists[loop_ref].refs + n]; + ir_insn *use_insn = &ctx->ir_base[use]; + + if (use_insn->op == IR_PHI) { + ir_ref op_ref = use_insn->op3; + ir_insn *op_insn = &ctx->ir_base[op_ref]; + + if (op_insn->op == IR_ADD || op_insn->op == IR_SUB || op_insn->op == IR_MUL) { + if (op_insn->op1 == use) { + if (ir_is_loop_invariant(ctx, op_insn->op2, loop_ref)) { + ir_iter_optimize_induction_var(ctx, use, op_ref, worklist); + } + } else if (op_insn->op2 == use) { + if (ir_is_loop_invariant(ctx, op_insn->op1, loop_ref)) { + ir_iter_optimize_induction_var(ctx, use, op_ref, worklist); + } + } + } + } + } +} + static ir_ref ir_iter_optimize_condition(ir_ctx *ctx, ir_ref control, ir_ref condition, bool *swap) { ir_insn *condition_insn = &ctx->ir_base[condition]; + while ((condition_insn->op == IR_BITCAST + || condition_insn->op == IR_ZEXT + || condition_insn->op == IR_SEXT) + && ctx->use_lists[condition].count == 1) { + condition = condition_insn->op1; + condition_insn = &ctx->ir_base[condition]; + } + if (condition_insn->opt == IR_OPT(IR_NOT, IR_BOOL)) { *swap = 1; condition = condition_insn->op1; @@ -2986,6 +3328,10 @@ static ir_ref ir_iter_optimize_condition(ir_ctx *ctx, ir_ref control, ir_ref con condition_insn = &ctx->ir_base[condition]; } + if (condition_insn->op == IR_ALLOCA || condition_insn->op == IR_VADDR) { + return IR_TRUE; + } + if (!IR_IS_CONST_REF(condition) && ctx->use_lists[condition].count > 1) { condition = ir_check_dominating_predicates(ctx, control, condition); } @@ -3032,6 +3378,7 @@ static void ir_iter_optimize_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu insn->optx = IR_OPTX(IR_END, IR_VOID, 1); if (!IR_IS_CONST_REF(insn->op2)) { ir_use_list_remove_one(ctx, insn->op2, ref); + ir_bitqueue_add(worklist, insn->op2); } insn->op2 = IR_UNUSED; @@ -3057,7 +3404,7 @@ static void ir_iter_optimize_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu static void ir_iter_optimize_guard(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist) { - bool swap; + bool swap = 0; ir_ref condition = ir_iter_optimize_condition(ctx, insn->op1, insn->op2, &swap); if (swap) { @@ -3158,7 +3505,7 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist) } goto folding; case IR_TRUNC: - if (ir_may_promote_i2i(ctx, insn->type, insn->op1)) { + if (ir_may_promote_trunc(ctx, insn->type, insn->op1)) { ir_ref ref = ir_promote_i2i(ctx, insn->type, insn->op1, i); insn->op1 = ref; ir_iter_replace_insn(ctx, i, ref, worklist); @@ -3183,12 +3530,13 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist) if (!(ctx->flags & IR_OPT_CFG)) { /* pass */ } else if (insn->op == IR_BEGIN) { - if (ctx->ir_base[insn->op1].op == IR_END - && ctx->use_lists[i].count == 1) { + if (insn->op1 && ctx->ir_base[insn->op1].op == IR_END) { ir_merge_blocks(ctx, insn->op1, i, worklist); } } else if (insn->op == IR_MERGE) { ir_iter_optimize_merge(ctx, i, insn, worklist); + } else if (insn->op == IR_LOOP_BEGIN) { + ir_iter_optimize_loop(ctx, i, insn, worklist); } } else if (ir_is_dead_load(ctx, i)) { ir_ref next; diff --git a/ext/opcache/jit/ir/ir_x86.dasc b/ext/opcache/jit/ir/ir_x86.dasc index c4f0eae01c004..3b6cf156ad909 100644 --- a/ext/opcache/jit/ir/ir_x86.dasc +++ b/ext/opcache/jit/ir/ir_x86.dasc @@ -1010,6 +1010,7 @@ const char *ir_reg_name(int8_t reg, ir_type type) _(MOD_PWR2) \ _(SDIV_PWR2) \ _(SMOD_PWR2) \ + _(BOOL_NOT) \ _(BOOL_NOT_INT) \ _(ABS_INT) \ _(OP_INT) \ @@ -2223,10 +2224,16 @@ binop_fp: ir_match_fuse_load(ctx, insn->op2, ref); return IR_MOD_INT; case IR_BSWAP: + IR_ASSERT(IR_IS_TYPE_INT(insn->type)); + return IR_OP_INT; case IR_NOT: if (insn->type == IR_BOOL) { - IR_ASSERT(IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)); // TODO: IR_BOOL_NOT_FP - return IR_BOOL_NOT_INT; + if (ctx->ir_base[insn->op1].type == IR_BOOL) { + return IR_BOOL_NOT; + } else { + IR_ASSERT(IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)); // TODO: IR_BOOL_NOT_FP + return IR_BOOL_NOT_INT; + } } else { IR_ASSERT(IR_IS_TYPE_INT(insn->type)); return IR_OP_INT; @@ -5054,6 +5061,33 @@ static void ir_emit_abs_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) } } +static void ir_emit_bool_not(ir_ctx *ctx, ir_ref def, ir_insn *insn) +{ + ir_backend_data *data = ctx->data; + dasm_State **Dst = &data->dasm_state; + ir_type type = ctx->ir_base[insn->op1].type; + ir_ref op1 = insn->op1; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op1_reg = ctx->regs[def][1]; + + IR_ASSERT(def_reg != IR_REG_NONE); + + if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { + op1_reg = IR_REG_NUM(op1_reg); + ir_emit_load(ctx, type, op1_reg, op1); + } + + if (def_reg != op1_reg) { + | mov Rb(def_reg), Rb(op1_reg) + } + + | xor Rb(def_reg), 1 + + if (IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); + } +} + static void ir_emit_bool_not_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; @@ -10602,6 +10636,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) case IR_ABS_INT: ir_emit_abs_int(ctx, i, insn); break; + case IR_BOOL_NOT: + ir_emit_bool_not(ctx, i, insn); + break; case IR_BOOL_NOT_INT: ir_emit_bool_not_int(ctx, i, insn); break; diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 77694e07d132e..2d4ef0bf4fc38 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -1316,7 +1316,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op uint32_t target_label, target_label2; uint32_t op1_info, op1_def_info, op2_info, res_info, res_use_info, op1_mem_info; zend_jit_addr op1_addr, op1_def_addr, op2_addr, op2_def_addr, res_addr; - zend_class_entry *ce; + zend_class_entry *ce = NULL; bool ce_is_instanceof; bool on_this; @@ -2335,11 +2335,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_IS: case ZEND_FETCH_OBJ_W: - if (opline->op2_type != IS_CONST - || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING - || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { - break; - } ce = NULL; ce_is_instanceof = 0; on_this = 0; @@ -2369,6 +2364,11 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } } } + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING + || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { + break; + } if (!zend_jit_fetch_obj(&ctx, opline, op_array, ssa, ssa_op, op1_info, op1_addr, 0, ce, ce_is_instanceof, on_this, 0, 0, NULL, RES_REG_ADDR(), IS_UNKNOWN, @@ -2709,6 +2709,36 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op /* We skip over the DO_FCALL, so decrement call_level ourselves. */ call_level--; } + break; + case ZEND_FETCH_OBJ_R: + if (!zend_jit_handler(&ctx, opline, + zend_may_throw(opline, ssa_op, op_array, ssa))) { + goto jit_failure; + } + + /* Cache slot is only used for IS_CONST op2, so only that can result in hook fast path. */ + if (opline->op2_type == IS_CONST) { + if (JIT_G(opt_level) < ZEND_JIT_LEVEL_INLINE) { + if (opline->op1_type == IS_UNUSED) { + ce = op_array->scope; + } else { + ce = NULL; + } + } + + if (!ce || !(ce->ce_flags & ZEND_ACC_FINAL) || ce->num_hooked_props > 0) { + /* If a simple hook is called, exit to the VM. */ + ir_ref if_hook_enter = ir_IF(jit_CMP_IP(jit, IR_EQ, opline + 1)); + ir_IF_FALSE(if_hook_enter); + if (GCC_GLOBAL_REGS) { + ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + } else { + ir_RETURN(ir_CONST_I32(1)); /* ZEND_VM_ENTER */ + } + ir_IF_TRUE(if_hook_enter); + } + } + break; default: if (!zend_jit_handler(&ctx, opline, diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 6a35eb7602e0e..0f5e1b11c3938 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1637,7 +1637,7 @@ static void ZEND_FASTCALL zend_jit_fast_assign_concat_helper(zval *op1, zval *op zend_string *result_str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(Z_STR_P(op1), Z_STR_P(op2)); - if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) { + if (UNEXPECTED(op1_len > ZSTR_MAX_LEN - op2_len)) { zend_throw_error(NULL, "String size overflow"); return; } @@ -1673,7 +1673,7 @@ static void ZEND_FASTCALL zend_jit_fast_concat_helper(zval *result, zval *op1, z zend_string *result_str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(Z_STR_P(op1), Z_STR_P(op2)); - if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) { + if (UNEXPECTED(op1_len > ZSTR_MAX_LEN - op2_len)) { zend_throw_error(NULL, "String size overflow"); return; } @@ -1697,7 +1697,7 @@ static void ZEND_FASTCALL zend_jit_fast_concat_tmp_helper(zval *result, zval *op zend_string *result_str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(Z_STR_P(op1), Z_STR_P(op2)); - if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) { + if (UNEXPECTED(op1_len > ZSTR_MAX_LEN - op2_len)) { zend_throw_error(NULL, "String size overflow"); return; } diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index b7841fd1701a8..7ff6522ba2c4a 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3558,6 +3558,8 @@ static void jit_IF_TRUE_FALSE_ex(zend_jit_ctx *jit, ir_ref if_ref, ir_ref true_b } } +static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ref switch_ref); + static void _zend_jit_add_predecessor_ref(zend_jit_ctx *jit, int b, int pred, ir_ref ref) { int i, *p; @@ -3580,6 +3582,9 @@ static void _zend_jit_add_predecessor_ref(zend_jit_ctx *jit, int b, int pred, ir } else if (jit->ctx.ir_base[ref].op == IR_IF) { jit_IF_TRUE_FALSE_ex(jit, ref, b); ref = ir_LOOP_END(); + } else if (jit->ctx.ir_base[ref].op == IR_SWITCH) { + zend_jit_case_start(jit, pred, b, ref); + ref = ir_LOOP_END(); } else if (jit->ctx.ir_base[ref].op == IR_UNREACHABLE) { ir_BEGIN(ref); ref = ir_LOOP_END(); @@ -4204,6 +4209,7 @@ static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_th case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_STATIC_PROP_REF: case ZEND_ASSIGN_OBJ_REF: + case ZEND_FRAMELESS_ICALL_3: zend_jit_set_last_valid_opline(jit, opline + 2); break; default: @@ -14743,13 +14749,6 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, // CACHE_PTR_EX(cache_slot + 2, NULL); } - if (RETURN_VALUE_USED(opline) && Z_MODE(res_addr) == IS_REG) { - zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); - if (!zend_jit_load_reg(jit, real_addr, res_addr, res_info)) { - return 0; - } - } - ir_END_list(end_inputs); ir_IF_FALSE(if_has_prop_info); } @@ -14815,12 +14814,6 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, arg3, arg4); - if (RETURN_VALUE_USED(opline) && Z_MODE(res_addr) == IS_REG) { - zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); - if (!zend_jit_load_reg(jit, real_addr, res_addr, res_info)) { - return 0; - } - } ir_END_list(end_inputs); } } @@ -14833,7 +14826,14 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, return 0; } } else { - if (!zend_jit_assign_to_variable(jit, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, res_addr, 0, 0)) { + zend_jit_addr real_res_addr; + + if (res_addr && Z_MODE(res_addr) == IS_REG) { + real_res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + } else { + real_res_addr = res_addr; + } + if (!zend_jit_assign_to_variable(jit, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, real_res_addr, 0, 0)) { return 0; } } @@ -14883,12 +14883,6 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS), arg5); - if (RETURN_VALUE_USED(opline) && Z_MODE(res_addr) == IS_REG) { - zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); - if (!zend_jit_load_reg(jit, real_addr, res_addr, res_info)) { - return 0; - } - } ir_END_list(end_inputs); } @@ -14909,6 +14903,13 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline); } + if (RETURN_VALUE_USED(opline) && Z_MODE(res_addr) == IS_REG) { + zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + if (!zend_jit_load_reg(jit, real_addr, res_addr, res_info)) { + return 0; + } + } + if (may_throw) { zend_jit_check_exception(jit); } diff --git a/ext/opcache/tests/gh18050.phpt b/ext/opcache/tests/gh18050.phpt new file mode 100644 index 0000000000000..3fb6c8d7b65ed --- /dev/null +++ b/ext/opcache/tests/gh18050.phpt @@ -0,0 +1,67 @@ +--TEST-- +GH-18050: Frameless calls break IN_ARRAY optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=%d, vars=%d, tmps=%d) + ; (after optimizer) + ; %sgh18050.php:%s +0000 INIT_FCALL 1 %d string("test") +0001 SEND_VAL string("x") 1 +0002 DO_UCALL +0003 INIT_FCALL 1 %d string("test") +0004 SEND_VAL string("z") 1 +0005 DO_UCALL +0006 RETURN int(1) + +test: + ; (lines=%d, args=%d, vars=%d, tmps=%d) + ; (after optimizer) + ; %sgh18050.php:%s +0000 CV0($v) = RECV 1 +0001 INIT_FCALL 1 %d string("var_dump") +0002 T1 = IN_ARRAY 0 CV0($v) array(...) +0003 SEND_VAL T1 1 +0004 DO_ICALL +0005 INIT_FCALL 1 %d string("var_dump") +0006 T1 = IN_ARRAY 0 CV0($v) array(...) +0007 SEND_VAL T1 1 +0008 DO_ICALL +0009 INIT_FCALL 1 %d string("var_dump") +0010 T1 = IN_ARRAY 1 CV0($v) array(...) +0011 SEND_VAL T1 1 +0012 DO_ICALL +0013 T1 = IN_ARRAY 1 CV0($v) array(...) +0014 JMPZ T1 0016 +0015 ECHO string("True +") +0016 RETURN null +bool(true) +bool(true) +bool(true) +True +bool(false) +bool(false) +bool(false) diff --git a/ext/opcache/tests/jit/gh15834.phpt b/ext/opcache/tests/jit/gh15834.phpt new file mode 100644 index 0000000000000..a8cc6ce7a15d6 --- /dev/null +++ b/ext/opcache/tests/jit/gh15834.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-15834 (Segfault with hook "simple get" cache slot and minimal JIT) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1111 +--FILE-- + $this->_prop; + } +} + +$a = new A; +for ($i=0;$i<5;$i++) { + echo $a->prop; + $a->_prop++; +} +?> +--EXPECT-- +12345 diff --git a/ext/opcache/tests/jit/gh17966.phpt b/ext/opcache/tests/jit/gh17966.phpt new file mode 100644 index 0000000000000..f9983ad4c2b36 --- /dev/null +++ b/ext/opcache/tests/jit/gh17966.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-17966 (Symfony JIT 1205 assertion failure) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1205 +--FILE-- + +--EXPECT-- +float(2.5) +float(1.25) diff --git a/ext/opcache/tests/jit/gh18037.phpt b/ext/opcache/tests/jit/gh18037.phpt new file mode 100644 index 0000000000000..26de60228e8cb --- /dev/null +++ b/ext/opcache/tests/jit/gh18037.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-18037 (SEGV Zend/zend_execute.c) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1201 +--FILE-- +matches(); +} + +test_helper(); +?> +--EXPECTF-- +Warning: Undefined array key 0 in %s on line %d + +Fatal error: Uncaught Error: Call to a member function matches() on array in %s:%d +Stack trace: +#0 %s(%d): test_helper() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/gh18113.phpt b/ext/opcache/tests/jit/gh18113.phpt new file mode 100644 index 0000000000000..194bb403032b9 --- /dev/null +++ b/ext/opcache/tests/jit/gh18113.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-18113 (stack-buffer-overflow ext/opcache/jit/ir/ir_sccp.c) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1205 +--FILE-- + +--EXPECT-- +Done diff --git a/ext/opcache/tests/opt/gh18107_1.phpt b/ext/opcache/tests/opt/gh18107_1.phpt new file mode 100644 index 0000000000000..c99fa7efa40d3 --- /dev/null +++ b/ext/opcache/tests/opt/gh18107_1.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-18107 (Opcache CFG jmp optimization with try-finally breaks the exception table) +--CREDITS-- +SpencerMalone +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=0x10 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 T1 = ISSET_ISEMPTY_CV (isset) CV0($badvar) +0001 JMPNZ T1 0006 +0002 V3 = NEW 1 string("Exception") +0003 SEND_VAL_EX string("Should happen") 1 +0004 DO_FCALL +0005 THROW V3 +0006 JMP 0006 +0007 V6 = NEW 1 string("Exception") +0008 SEND_VAL_EX string("Should not happen") 1 +0009 DO_FCALL +0010 THROW V6 +0011 FAST_RET T5 +EXCEPTION TABLE: + 0006, -, 0007, 0011 +Fatal error: Uncaught Exception: Should happen in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/opt/gh18107_2.phpt b/ext/opcache/tests/opt/gh18107_2.phpt new file mode 100644 index 0000000000000..573bcd5ae4a6f --- /dev/null +++ b/ext/opcache/tests/opt/gh18107_2.phpt @@ -0,0 +1,54 @@ +--TEST-- +GH-18107 (Opcache CFG jmp optimization with try-finally breaks the exception table) +--CREDITS-- +SpencerMalone +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=0x10 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 T2 = ISSET_ISEMPTY_CV (isset) CV0($badvar) +0001 JMPNZ T2 0008 +0002 V4 = NEW 1 string("Exception") +0003 SEND_VAL_EX string("Should happen") 1 +0004 DO_FCALL +0005 THROW V4 +0006 CV1($e) = CATCH string("Throwable") +0007 ECHO string("foo") +0008 T6 = FAST_CALL 0010 +0009 JMP 0015 +0010 V7 = NEW 1 string("Exception") +0011 SEND_VAL_EX string("Should not happen") 1 +0012 DO_FCALL +0013 THROW V7 +0014 FAST_RET T6 +0015 RETURN int(1) +EXCEPTION TABLE: + 0006, 0006, 0010, 0014 +Fatal error: Uncaught Exception: Should happen in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/ext/openssl/tests/CertificateGenerator.inc b/ext/openssl/tests/CertificateGenerator.inc index 12764c8b63d2c..6fd73e0e9bed1 100644 --- a/ext/openssl/tests/CertificateGenerator.inc +++ b/ext/openssl/tests/CertificateGenerator.inc @@ -4,26 +4,33 @@ class CertificateGenerator { const CONFIG = __DIR__. DIRECTORY_SEPARATOR . 'openssl.cnf'; - /** @var OpenSSLCertificate */ - private $ca; + /** @var OpenSSLCertificate|false */ + private $ca = false; - /** @var resource */ - private $caKey; + /** @var OpenSSLAsymmetricKey|false */ + private $caKey = false; - /** @var resource|null */ + /** @var bool */ + private $useSelfSignedCert; + + /** @var OpenSSLCertificate|null */ private $lastCert; - /** @var resource|null */ + /** @var OpenSSLAsymmetricKey|null */ private $lastKey; - public function __construct() + public function __construct(bool $useSelfSignedCert = false) { if (!extension_loaded('openssl')) { throw new RuntimeException( 'openssl extension must be loaded to generate certificates' ); } - $this->generateCa(); + $this->useSelfSignedCert = $useSelfSignedCert; + + if (!$this->useSelfSignedCert) { + $this->generateCa(); + } } /** @@ -54,40 +61,32 @@ class CertificateGenerator 'commonName' => 'CA for PHP Tests' ]; - $this->ca = openssl_csr_sign( - openssl_csr_new( - $dn, - $this->caKey, - [ - 'x509_extensions' => 'v3_ca', - 'config' => self::CONFIG, - ] - ), - null, - $this->caKey, - 2, - [ - 'config' => self::CONFIG, - ] - ); + $csr = openssl_csr_new($dn, $this->caKey, ['config' => self::CONFIG]); + $this->ca = openssl_csr_sign($csr, null, $this->caKey, 365, ['config' => self::CONFIG]); } public function getCaCert() { + if ($this->useSelfSignedCert) { + throw new RuntimeException("CA is not generated in self-signed mode."); + } + $output = ''; openssl_x509_export($this->ca, $output); - return $output; } public function saveCaCert($file) { + if ($this->useSelfSignedCert) { + throw new RuntimeException("CA is not available in self-signed mode."); + } + openssl_x509_export_to_file($this->ca, $file); } - private function generateCertAndKey( - $commonNameForCert, $file, $keyLength = null, $subjectAltName = null - ) { + private function generateCertAndKey($commonNameForCert, $file, $keyLength = null, $subjectAltName = null) + { $dn = [ 'countryName' => 'BY', 'stateOrProvinceName' => 'Minsk', @@ -98,8 +97,7 @@ class CertificateGenerator $dn['commonName'] = $commonNameForCert; } - $subjectAltNameConfig = - $subjectAltName ? "subjectAltName = $subjectAltName" : ""; + $subjectAltNameConfig = $subjectAltName ? "subjectAltName = $subjectAltName" : ""; $configCode = <<lastKey = self::generateKey($keyLength); $csr = openssl_csr_new($dn, $this->lastKey, $config); + + // If in self-signed mode, sign with the same key, otherwise use CA + $signingCert = $this->useSelfSignedCert ? null : $this->ca; + $signingKey = $this->useSelfSignedCert ? $this->lastKey : $this->caKey; + $this->lastCert = openssl_csr_sign( $csr, - $this->ca, - $this->caKey, - /* days */ 2, - $config, + $signingCert, + $signingKey, + 365, // 1 year validity + $config ); return $config; @@ -166,6 +169,22 @@ CONFIG; unlink($config['config']); } + public function saveNewCertAndPubKey( + $commonNameForCert, $certFile, $pubKeyFile, $keyLength = null, $subjectAltName = null + ) { + $config = $this->generateCertAndKey($commonNameForCert, $certFile, $keyLength, $subjectAltName); + + openssl_x509_export_to_file($this->lastCert, $certFile); + + $keyDetails = openssl_pkey_get_details($this->lastKey); + if ($keyDetails === false || !isset($keyDetails['key'])) { + throw new RuntimeException("Failed to extract public key."); + } + + file_put_contents($pubKeyFile, $keyDetails['key']); + unlink($config['config']); + } + public function getCertDigest($algo) { return openssl_x509_fingerprint($this->lastCert, $algo); diff --git a/ext/openssl/tests/openssl_x509_verify.phpt b/ext/openssl/tests/openssl_x509_verify.phpt index 083d4669c4229..4b6e758857d27 100644 --- a/ext/openssl/tests/openssl_x509_verify.phpt +++ b/ext/openssl/tests/openssl_x509_verify.phpt @@ -4,16 +4,24 @@ openssl_x509_verify() tests openssl --FILE-- saveNewCertAndPubKey('openssl-x509-verify-server', $certFile, $keyFile); + +$fp = fopen($certFile,"r"); $a = fread($fp, 8192); fclose($fp); -$fp = fopen(__DIR__ . "/public.key","r"); +$fp = fopen($keyFile,"r"); $b = fread($fp, 8192); fclose($fp); -$cert = "file://" . __DIR__ . "/cert.crt"; -$key = "file://" . __DIR__ . "/public.key"; +$cert = "file://" . $certFile; +$key = "file://" . $keyFile; $wrongKey = "file://" . __DIR__ . "/public_rsa_2048.key"; var_dump(openssl_x509_verify($cert, $key)); @@ -23,6 +31,11 @@ var_dump(openssl_x509_verify("", "")); var_dump(openssl_x509_verify(openssl_x509_read($a), $b)); var_dump(openssl_x509_verify($cert, $wrongKey)); ?> +--CLEAN-- + --EXPECT-- int(1) int(-1) diff --git a/ext/pcre/tests/bug75457.phpt b/ext/pcre/tests/bug75457.phpt index ee5ab162f8a6c..1401b25ff6fb7 100644 --- a/ext/pcre/tests/bug75457.phpt +++ b/ext/pcre/tests/bug75457.phpt @@ -6,5 +6,5 @@ $pattern = "/(((?(?C)0?=))(?!()0|.(?0)0)())/"; var_dump(preg_match($pattern, "hello")); ?> --EXPECTF-- -Warning: preg_match(): Compilation failed: assertion expected after (?( or (?(?C) at offset 8 in %sbug75457.php on line %d +Warning: preg_match(): Compilation failed:%r( atomic|)%r assertion expected after (?( or (?(?C) at offset 8 in %sbug75457.php on line %d bool(false) diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 94106b715ef56..006e49461f646 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -2491,6 +2491,7 @@ static zval *pdo_row_get_property_ptr_ptr(zend_object *object, zend_string *name ZEND_IGNORE_VALUE(type); ZEND_IGNORE_VALUE(cache_slot); + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; return NULL; } @@ -2501,6 +2502,7 @@ void pdo_row_free_storage(zend_object *std) ZVAL_UNDEF(&row->stmt->lazy_object_ref); OBJ_RELEASE(&row->stmt->std); } + zend_object_std_dtor(std); } zend_object *pdo_row_new(zend_class_entry *ce) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 08764ecf45a30..136483a149696 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -684,7 +684,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */ /* make all parameters nullable */ unsigned int i; - XSQLVAR* var; + XSQLVAR* var; for (i = 0, var = S->in_sqlda->sqlvar; i < S->in_sqlda->sqld; i++, var++) { /* The low bit of sqltype indicates that the parameter can take a NULL value */ var->sqltype |= 1; @@ -1431,7 +1431,7 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* "HY000", H->isc_status[1], errmsg); } - if (dbh->auto_commit && !H->tr) { + if (ret && dbh->auto_commit && !H->tr) { ret = php_firebird_begin_transaction(dbh, /* auto commit mode */ true); } diff --git a/ext/pdo_pgsql/tests/pdopgsql_003.phpt b/ext/pdo_pgsql/tests/pdopgsql_003.phpt index 378a15c86da99..2902590f1f490 100644 --- a/ext/pdo_pgsql/tests/pdopgsql_003.phpt +++ b/ext/pdo_pgsql/tests/pdopgsql_003.phpt @@ -27,6 +27,6 @@ try { echo $e->getMessage() . "\n"; } ---EXPECT-- +--EXPECTF-- "This is a quote""" -SQLSTATE[HY000]: General error: 7 incomplete multibyte character +SQLSTATE[HY000]: General error: 7 %r(incomplete|invalid)%r multibyte character diff --git a/ext/pdo_sqlite/tests/gh18114.phpt b/ext/pdo_sqlite/tests/gh18114.phpt new file mode 100644 index 0000000000000..850558845485a --- /dev/null +++ b/ext/pdo_sqlite/tests/gh18114.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-18114 (pdo lazy object crash) +--EXTENSIONS-- +pdo_sqlite +--FILE-- +query('select 1 as queryString'); +$data = $x->fetch(PDO::FETCH_LAZY); +foreach ($data as $entry) { + var_dump($entry); +} +var_dump((array) $data); +echo "Done\n"; +?> +--EXPECT-- +array(0) { +} +Done diff --git a/ext/reflection/tests/ReflectionFunction_isDeprecated_magic_call.phpt b/ext/reflection/tests/ReflectionFunction_isDeprecated_magic_call.phpt new file mode 100644 index 0000000000000..fa63816c44ec7 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isDeprecated_magic_call.phpt @@ -0,0 +1,70 @@ +--TEST-- +GH-17913: ReflectionClassConstant::isDeprecated() with __call() and __callStatic() +--FILE-- +getAttributes()[0]->newInstance()); +var_dump($rc->isDeprecated()); + +$closure = $foo->test(...); + +$rc = new ReflectionFunction($closure); +var_dump($rc->getAttributes()[0]->newInstance()); +var_dump($rc->isDeprecated()); + +$closure = Closure::fromCallable('Clazz::test'); + +$rc = new ReflectionFunction($closure); +var_dump($rc->getAttributes()[0]->newInstance()); +var_dump($rc->isDeprecated()); + +$closure = Clazz::test(...); + +$rc = new ReflectionFunction($closure); +var_dump($rc->getAttributes()[0]->newInstance()); +var_dump($rc->isDeprecated()); + +?> +--EXPECTF-- +object(Deprecated)#%d (2) { + ["message"]=> + NULL + ["since"]=> + NULL +} +bool(true) +object(Deprecated)#%d (2) { + ["message"]=> + NULL + ["since"]=> + NULL +} +bool(true) +object(Deprecated)#%d (2) { + ["message"]=> + string(18) "due to some reason" + ["since"]=> + NULL +} +bool(true) +object(Deprecated)#%d (2) { + ["message"]=> + string(18) "due to some reason" + ["since"]=> + NULL +} +bool(true) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index df4640e59dd42..d119063502c0c 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -639,6 +639,8 @@ static zval *sxe_property_get_adr(zend_object *object, zend_string *zname, int f SXE_ITER type; zval member; + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + sxe = php_sxe_fetch_object(object); GET_NODE(sxe, node); if (UNEXPECTED(!node)) { diff --git a/ext/simplexml/tests/bug51615.phpt b/ext/simplexml/tests/bug51615.phpt index b0ac921fead2a..7245434ff5578 100644 --- a/ext/simplexml/tests/bug51615.phpt +++ b/ext/simplexml/tests/bug51615.phpt @@ -7,7 +7,7 @@ dom loadHTML('xx'); +$dom->loadHTML('xx', LIBXML_NOERROR); $html = simplexml_import_dom($dom); var_dump($html->body->span); @@ -18,15 +18,12 @@ foreach ($html->body->span as $obj) { ?> --EXPECTF-- -Warning: DOMDocument::loadHTML(): error parsing attribute name in Entity, line: 1 in %s on line %d - -Warning: DOMDocument::loadHTML(): error parsing attribute name in Entity, line: 1 in %s on line %d object(SimpleXMLElement)#%d (3) { ["@attributes"]=> array(2) { ["title"]=> string(0) "" - ["y"]=> + [%r("y"{1,2})%r]=> string(0) "" } [0]=> diff --git a/ext/simplexml/tests/gh17736.phpt b/ext/simplexml/tests/gh17736.phpt new file mode 100644 index 0000000000000..78561f6ab0293 --- /dev/null +++ b/ext/simplexml/tests/gh17736.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-17736 (Assertion failure zend_reference_destroy()) +--EXTENSIONS-- +simplexml +--FILE-- +'); +class C { + public int $a = 1; +} +function test($obj) { + $ref =& $obj->a; +} +$obj = new C; +test($obj); +test($o1); +echo "Done\n"; +?> +--EXPECT-- +Done diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 91b530f3b39d7..354ac2e5178d0 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1861,6 +1861,7 @@ static zval *php_snmp_get_property_ptr_ptr(zend_object *object, zend_string *nam return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; return NULL; } diff --git a/ext/snmp/tests/gh16959.phpt b/ext/snmp/tests/gh16959.phpt index ce647b15b9dac..cabe0eb84b6cb 100644 --- a/ext/snmp/tests/gh16959.phpt +++ b/ext/snmp/tests/gh16959.phpt @@ -5,6 +5,7 @@ snmp --SKIPIF-- --FILE-- children != NULL) { zval zv; master_to_zval(&zv, get_conversion(IS_STRING), tmp); + convert_to_string(&zv) faultstring = Z_STR(zv); } @@ -199,6 +200,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio if (tmp != NULL && tmp->children != NULL) { zval zv; master_to_zval(&zv, get_conversion(IS_STRING), tmp); + convert_to_string(&zv) faultactor = Z_STR(zv); } @@ -222,6 +224,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio if (tmp != NULL && tmp->children != NULL) { zval zv; master_to_zval(&zv, get_conversion(IS_STRING), tmp); + convert_to_string(&zv) faultstring = Z_STR(zv); } } diff --git a/ext/soap/tests/bugs/bug66049.phpt b/ext/soap/tests/bugs/bug66049.phpt new file mode 100644 index 0000000000000..e48845a8a142b --- /dev/null +++ b/ext/soap/tests/bugs/bug66049.phpt @@ -0,0 +1,48 @@ +--TEST-- +Fix #66049 Typemap can break parsing in parse_packet_soap leading to a segfault +--EXTENSIONS-- +soap +--INI-- +soap.wsdl_cache_enabled=0 +--FILE-- + + + + SOAP-ENV:Servernot present + '; + return $res; + } +} + +try { + $client=new TestSoapClient(null, [ + 'uri' => 'test://', + 'location' => 'test://', + 'typemap' => [[ + "type_ns" => "http://www.w3.org/2001/XMLSchema", + "type_name" => "string", + "from_xml" => "soap_string_from_xml" + ]]]); + $client->Mist(""); +} catch (SoapFault $e) { + var_dump($e->faultstring); + var_dump($e->faultcode); +} +?> +Done +--EXPECT-- +soap_string_from_xml +string(3) "2.3" +string(15) "SOAP-ENV:Server" +Done diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index e7716b6ccb0fa..676d35bd42991 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -915,7 +915,7 @@ PHP_FUNCTION(socket_read) ENSURE_SOCKET_VALID(php_sock); /* overflow check */ - if ((length + 1) < 2) { + if (length <= 0 || length == ZEND_LONG_MAX) { RETURN_FALSE; } @@ -1365,7 +1365,7 @@ PHP_FUNCTION(socket_recv) ENSURE_SOCKET_VALID(php_sock); /* overflow check */ - if ((len + 1) < 2) { + if (len <= 0 || len == ZEND_LONG_MAX) { RETURN_FALSE; } diff --git a/ext/sockets/tests/gh17921.phpt b/ext/sockets/tests/gh17921.phpt new file mode 100644 index 0000000000000..d038ed04bc946 --- /dev/null +++ b/ext/sockets/tests/gh17921.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-16267 - overflow on socket_strerror argument +--EXTENSIONS-- +sockets +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index db7f4fff9bb04..49ed056771114 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -665,12 +665,14 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object } } + /* empty() check the value is not falsy, isset() only check it is not null */ + bool result = check_empty ? zend_is_true(value) : Z_TYPE_P(value) != IS_NULL; + if (value == &rv) { zval_ptr_dtor(&rv); } - /* empty() check the value is not falsy, isset() only check it is not null */ - return check_empty ? zend_is_true(value) : Z_TYPE_P(value) != IS_NULL; + return result; } /* }}} */ static int spl_array_has_dimension(zend_object *object, zval *offset, int check_empty) /* {{{ */ @@ -861,6 +863,8 @@ static zval *spl_array_get_property_ptr_ptr(zend_object *object, zend_string *na if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 && !zend_std_has_property(object, name, ZEND_PROPERTY_EXISTS, NULL)) { + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + /* If object has offsetGet() overridden, then fallback to read_property, * which will call offsetGet(). */ zval member; diff --git a/ext/spl/tests/gh18018.phpt b/ext/spl/tests/gh18018.phpt new file mode 100644 index 0000000000000..06fa7fc3d0e55 --- /dev/null +++ b/ext/spl/tests/gh18018.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-18018 (RC1 data returned from offsetGet causes UAF in ArrayObject) +--FILE-- + 1]; + +$object = new Crap($values); + +var_dump(empty($object['qux'])); +?> +--EXPECT-- +bool(false) diff --git a/ext/standard/array.c b/ext/standard/array.c index 6bfc0dc9c0403..0c2de2a98a1d9 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6628,7 +6628,8 @@ static zend_result php_array_find(const HashTable *array, zend_fcall_info fci, z ZVAL_COPY(&args[0], operand); zend_result result = zend_call_function(&fci, &fci_cache); - if (EXPECTED(result == SUCCESS)) { + ZEND_ASSERT(result == SUCCESS); + if (EXPECTED(!Z_ISUNDEF(retval))) { int retval_true; retval_true = zend_is_true(&retval); @@ -6656,7 +6657,7 @@ static zend_result php_array_find(const HashTable *array, zend_fcall_info fci, z zval_ptr_dtor(&args[0]); zval_ptr_dtor(&args[1]); - if (UNEXPECTED(result != SUCCESS)) { + if (UNEXPECTED(Z_ISUNDEF(retval))) { return FAILURE; } } ZEND_HASH_FOREACH_END(); @@ -6725,7 +6726,11 @@ PHP_FUNCTION(array_any) RETURN_THROWS(); } - RETURN_BOOL(Z_TYPE_P(return_value) != IS_UNDEF); + bool retval = !Z_ISUNDEF_P(return_value); + if (Z_TYPE_P(return_value) == IS_STRING) { + zval_ptr_dtor_str(return_value); + } + RETURN_BOOL(retval); } /* }}} */ @@ -6745,7 +6750,11 @@ PHP_FUNCTION(array_all) RETURN_THROWS(); } - RETURN_BOOL(Z_TYPE_P(return_value) == IS_UNDEF); + bool retval = Z_ISUNDEF_P(return_value); + if (Z_TYPE_P(return_value) == IS_STRING) { + zval_ptr_dtor_str(return_value); + } + RETURN_BOOL(retval); } /* }}} */ diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index fff6af5e2143c..ea06e9dff61ea 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -67,15 +67,16 @@ #include "php_fopen_wrappers.h" -#define HTTP_HEADER_BLOCK_SIZE 1024 -#define PHP_URL_REDIRECT_MAX 20 -#define HTTP_HEADER_USER_AGENT 1 -#define HTTP_HEADER_HOST 2 -#define HTTP_HEADER_AUTH 4 -#define HTTP_HEADER_FROM 8 -#define HTTP_HEADER_CONTENT_LENGTH 16 -#define HTTP_HEADER_TYPE 32 -#define HTTP_HEADER_CONNECTION 64 +#define HTTP_HEADER_BLOCK_SIZE 1024 +#define HTTP_HEADER_MAX_LOCATION_SIZE 8182 /* 8192 - 10 (size of "Location: ") */ +#define PHP_URL_REDIRECT_MAX 20 +#define HTTP_HEADER_USER_AGENT 1 +#define HTTP_HEADER_HOST 2 +#define HTTP_HEADER_AUTH 4 +#define HTTP_HEADER_FROM 8 +#define HTTP_HEADER_CONTENT_LENGTH 16 +#define HTTP_HEADER_TYPE 32 +#define HTTP_HEADER_CONNECTION 64 #define HTTP_WRAPPER_HEADER_INIT 1 #define HTTP_WRAPPER_REDIRECTED 2 @@ -107,7 +108,7 @@ static inline void strip_header(char *header_bag, char *lc_header_bag, static bool check_has_header(const char *headers, const char *header) { const char *s = headers; while ((s = strstr(s, header))) { - if (s == headers || *(s-1) == '\n') { + if (s == headers || (*(s-1) == '\n' && *(s-2) == '\r')) { return 1; } s++; @@ -143,6 +144,214 @@ static zend_result php_stream_handle_proxy_authorization_header(const char *s, s return FAILURE; } +typedef struct _php_stream_http_response_header_info { + php_stream_filter *transfer_encoding; + size_t file_size; + bool error; + bool follow_location; + char *location; + size_t location_len; +} php_stream_http_response_header_info; + +static void php_stream_http_response_header_info_init( + php_stream_http_response_header_info *header_info) +{ + memset(header_info, 0, sizeof(php_stream_http_response_header_info)); + header_info->follow_location = 1; +} + +/* Trim white spaces from response header line and update its length */ +static bool php_stream_http_response_header_trim(char *http_header_line, + size_t *http_header_line_length) +{ + char *http_header_line_end = http_header_line + *http_header_line_length - 1; + while (http_header_line_end >= http_header_line && + (*http_header_line_end == '\n' || *http_header_line_end == '\r')) { + http_header_line_end--; + } + + /* The primary definition of an HTTP header in RFC 7230 states: + * > Each header field consists of a case-insensitive field name followed + * > by a colon (":"), optional leading whitespace, the field value, and + * > optional trailing whitespace. */ + + /* Strip trailing whitespace */ + bool space_trim = (*http_header_line_end == ' ' || *http_header_line_end == '\t'); + if (space_trim) { + do { + http_header_line_end--; + } while (http_header_line_end >= http_header_line && + (*http_header_line_end == ' ' || *http_header_line_end == '\t')); + } + http_header_line_end++; + *http_header_line_end = '\0'; + *http_header_line_length = http_header_line_end - http_header_line; + + return space_trim; +} + +/* Process folding headers of the current line and if there are none, parse last full response + * header line. It returns NULL if the last header is finished, otherwise it returns updated + * last header line. */ +static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *wrapper, + php_stream *stream, php_stream_context *context, int options, + zend_string *last_header_line_str, char *header_line, size_t *header_line_length, + int response_code, zval *response_header, + php_stream_http_response_header_info *header_info) +{ + char *last_header_line = ZSTR_VAL(last_header_line_str); + size_t last_header_line_length = ZSTR_LEN(last_header_line_str); + char *last_header_line_end = ZSTR_VAL(last_header_line_str) + ZSTR_LEN(last_header_line_str) - 1; + + /* Process non empty header line. */ + if (header_line && (*header_line != '\n' && *header_line != '\r')) { + /* Removing trailing white spaces. */ + if (php_stream_http_response_header_trim(header_line, header_line_length) && + *header_line_length == 0) { + /* Only spaces so treat as an empty folding header. */ + return last_header_line_str; + } + + /* Process folding headers if starting with a space or a tab. */ + if (header_line && (*header_line == ' ' || *header_line == '\t')) { + char *http_folded_header_line = header_line; + size_t http_folded_header_line_length = *header_line_length; + /* Remove the leading white spaces. */ + while (*http_folded_header_line == ' ' || *http_folded_header_line == '\t') { + http_folded_header_line++; + http_folded_header_line_length--; + } + /* It has to have some characters because it would get returned after the call + * php_stream_http_response_header_trim above. */ + ZEND_ASSERT(http_folded_header_line_length > 0); + /* Concatenate last header line, space and current header line. */ + zend_string *extended_header_str = zend_string_concat3( + last_header_line, last_header_line_length, + " ", 1, + http_folded_header_line, http_folded_header_line_length); + zend_string_efree(last_header_line_str); + last_header_line_str = extended_header_str; + /* Return new header line. */ + return last_header_line_str; + } + } + + /* Find header separator position. */ + char *last_header_value = memchr(last_header_line, ':', last_header_line_length); + if (last_header_value) { + /* Verify there is no space in header name */ + char *last_header_name = last_header_line + 1; + while (last_header_name < last_header_value) { + if (*last_header_name == ' ' || *last_header_name == '\t') { + header_info->error = true; + php_stream_wrapper_log_error(wrapper, options, + "HTTP invalid response format (space in header name)!"); + zend_string_efree(last_header_line_str); + return NULL; + } + ++last_header_name; + } + + last_header_value++; /* Skip ':'. */ + + /* Strip leading whitespace. */ + while (last_header_value < last_header_line_end + && (*last_header_value == ' ' || *last_header_value == '\t')) { + last_header_value++; + } + } else { + /* There is no colon which means invalid response so error. */ + header_info->error = true; + php_stream_wrapper_log_error(wrapper, options, + "HTTP invalid response format (no colon in header line)!"); + zend_string_efree(last_header_line_str); + return NULL; + } + + bool store_header = true; + zval *tmpzval = NULL; + + if (!strncasecmp(last_header_line, "Location:", sizeof("Location:")-1)) { + /* Check if the location should be followed. */ + if (context && (tmpzval = php_stream_context_get_option(context, "http", "follow_location")) != NULL) { + header_info->follow_location = zval_is_true(tmpzval); + } else if (!((response_code >= 300 && response_code < 304) + || 307 == response_code || 308 == response_code)) { + /* The redirection should not be automatic if follow_location is not set and + * response_code not in (300, 301, 302, 303 and 307) + * see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 + * RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */ + header_info->follow_location = 0; + } + size_t last_header_value_len = strlen(last_header_value); + if (last_header_value_len > HTTP_HEADER_MAX_LOCATION_SIZE) { + header_info->error = true; + php_stream_wrapper_log_error(wrapper, options, + "HTTP Location header size is over the limit of %d bytes", + HTTP_HEADER_MAX_LOCATION_SIZE); + zend_string_efree(last_header_line_str); + return NULL; + } + if (header_info->location_len == 0) { + header_info->location = emalloc(last_header_value_len + 1); + } else if (header_info->location_len <= last_header_value_len) { + header_info->location = erealloc(header_info->location, last_header_value_len + 1); + } + header_info->location_len = last_header_value_len; + memcpy(header_info->location, last_header_value, last_header_value_len + 1); + } else if (!strncasecmp(last_header_line, "Content-Type:", sizeof("Content-Type:")-1)) { + php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, last_header_value, 0); + } else if (!strncasecmp(last_header_line, "Content-Length:", sizeof("Content-Length:")-1)) { + /* https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length */ + const char *ptr = last_header_value; + /* must contain only digits, no + or - symbols */ + if (*ptr >= '0' && *ptr <= '9') { + char *endptr = NULL; + size_t parsed = ZEND_STRTOUL(ptr, &endptr, 10); + /* check whether there was no garbage in the header value and the conversion was successful */ + if (endptr && !*endptr) { + /* truncate for 32-bit such that no negative file sizes occur */ + header_info->file_size = MIN(parsed, ZEND_LONG_MAX); + php_stream_notify_file_size(context, header_info->file_size, last_header_line, 0); + } + } + } else if ( + !strncasecmp(last_header_line, "Transfer-Encoding:", sizeof("Transfer-Encoding:")-1) + && !strncasecmp(last_header_value, "Chunked", sizeof("Chunked")-1) + ) { + /* Create filter to decode response body. */ + if (!(options & STREAM_ONLY_GET_HEADERS)) { + bool decode = true; + + if (context && (tmpzval = php_stream_context_get_option(context, "http", "auto_decode")) != NULL) { + decode = zend_is_true(tmpzval); + } + if (decode) { + if (header_info->transfer_encoding != NULL) { + /* Prevent a memory leak in case there are more transfer-encoding headers. */ + php_stream_filter_free(header_info->transfer_encoding); + } + header_info->transfer_encoding = php_stream_filter_create( + "dechunk", NULL, php_stream_is_persistent(stream)); + if (header_info->transfer_encoding != NULL) { + /* Do not store transfer-encoding header. */ + store_header = false; + } + } + } + } + + if (store_header) { + zval http_header; + ZVAL_NEW_STR(&http_header, last_header_line_str); + zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header); + } else { + zend_string_efree(last_header_line_str); + } + + return NULL; +} + static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context, int redirect_max, int flags, @@ -155,11 +364,12 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, zend_string *tmp = NULL; char *ua_str = NULL; zval *ua_zval = NULL, *tmpzval = NULL, ssl_proxy_peer_name; - char location[HTTP_HEADER_BLOCK_SIZE]; int reqok = 0; char *http_header_line = NULL; + zend_string *last_header_line_str = NULL; + php_stream_http_response_header_info header_info; char tmp_line[128]; - size_t chunk_size = 0, file_size = 0; + size_t chunk_size = 0; int eol_detect = 0; zend_string *transport_string; zend_string *errstr = NULL; @@ -170,8 +380,6 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0); int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0); int redirect_keep_method = ((flags & HTTP_WRAPPER_KEEP_METHOD) != 0); - bool follow_location = 1; - php_stream_filter *transfer_encoding = NULL; int response_code; smart_str req_buf = {0}; bool custom_request_method; @@ -360,6 +568,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } } + php_stream_http_response_header_info_init(&header_info); + if (stream == NULL) goto out; @@ -660,8 +870,6 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* send it */ php_stream_write(stream, ZSTR_VAL(req_buf.s), ZSTR_LEN(req_buf.s)); - location[0] = '\0'; - if (Z_ISUNDEF_P(response_header)) { array_init(response_header); } @@ -744,140 +952,103 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } /* read past HTTP headers */ - while (!php_stream_eof(stream)) { size_t http_header_line_length; if (http_header_line != NULL) { efree(http_header_line); } - if ((http_header_line = php_stream_get_line(stream, NULL, 0, &http_header_line_length)) && *http_header_line != '\n' && *http_header_line != '\r') { - char *e = http_header_line + http_header_line_length - 1; - char *http_header_value; - - while (e >= http_header_line && (*e == '\n' || *e == '\r')) { - e--; - } - - /* The primary definition of an HTTP header in RFC 7230 states: - * > Each header field consists of a case-insensitive field name followed - * > by a colon (":"), optional leading whitespace, the field value, and - * > optional trailing whitespace. */ - - /* Strip trailing whitespace */ - while (e >= http_header_line && (*e == ' ' || *e == '\t')) { - e--; - } - - /* Terminate header line */ - e++; - *e = '\0'; - http_header_line_length = e - http_header_line; - - http_header_value = memchr(http_header_line, ':', http_header_line_length); - if (http_header_value) { - http_header_value++; /* Skip ':' */ - - /* Strip leading whitespace */ - while (http_header_value < e - && (*http_header_value == ' ' || *http_header_value == '\t')) { - http_header_value++; + if ((http_header_line = php_stream_get_line(stream, NULL, 0, &http_header_line_length))) { + bool last_line; + if (*http_header_line == '\r') { + if (http_header_line[1] != '\n') { + php_stream_close(stream); + stream = NULL; + php_stream_wrapper_log_error(wrapper, options, + "HTTP invalid header name (cannot start with CR character)!"); + goto out; } + last_line = true; + } else if (*http_header_line == '\n') { + last_line = true; } else { - /* There is no colon. Set the value to the end of the header line, which is - * effectively an empty string. */ - http_header_value = e; + last_line = false; } - - if (!strncasecmp(http_header_line, "Location:", sizeof("Location:")-1)) { - if (context && (tmpzval = php_stream_context_get_option(context, "http", "follow_location")) != NULL) { - follow_location = zval_is_true(tmpzval); - } else if (!((response_code >= 300 && response_code < 304) - || 307 == response_code || 308 == response_code)) { - /* we shouldn't redirect automatically - if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307) - see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 - RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */ - follow_location = 0; - } - strlcpy(location, http_header_value, sizeof(location)); - } else if (!strncasecmp(http_header_line, "Content-Type:", sizeof("Content-Type:")-1)) { - php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_value, 0); - } else if (!strncasecmp(http_header_line, "Content-Length:", sizeof("Content-Length:")-1)) { - /* https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length */ - const char *ptr = http_header_value; - /* must contain only digits, no + or - symbols */ - if (*ptr >= '0' && *ptr <= '9') { - char *endptr = NULL; - size_t parsed = ZEND_STRTOUL(ptr, &endptr, 10); - /* check whether there was no garbage in the header value and the conversion was successful */ - if (endptr && !*endptr) { - /* truncate for 32-bit such that no negative file sizes occur */ - file_size = MIN(parsed, ZEND_LONG_MAX); - php_stream_notify_file_size(context, file_size, http_header_line, 0); + + if (last_header_line_str != NULL) { + /* Parse last header line. */ + last_header_line_str = php_stream_http_response_headers_parse(wrapper, stream, + context, options, last_header_line_str, http_header_line, + &http_header_line_length, response_code, response_header, &header_info); + if (EXPECTED(last_header_line_str == NULL)) { + if (UNEXPECTED(header_info.error)) { + php_stream_close(stream); + stream = NULL; + goto out; } + } else { + /* Folding header present so continue. */ + continue; } - } else if ( - !strncasecmp(http_header_line, "Transfer-Encoding:", sizeof("Transfer-Encoding:")-1) - && !strncasecmp(http_header_value, "Chunked", sizeof("Chunked")-1) - ) { - - /* create filter to decode response body */ - if (!(options & STREAM_ONLY_GET_HEADERS)) { - bool decode = true; - - if (context && (tmpzval = php_stream_context_get_option(context, "http", "auto_decode")) != NULL) { - decode = zend_is_true(tmpzval); - } - if (decode) { - transfer_encoding = php_stream_filter_create("dechunk", NULL, php_stream_is_persistent(stream)); - if (transfer_encoding) { - /* don't store transfer-encodeing header */ - continue; - } - } + } else if (!last_line) { + /* The first line cannot start with spaces. */ + if (*http_header_line == ' ' || *http_header_line == '\t') { + php_stream_close(stream); + stream = NULL; + php_stream_wrapper_log_error(wrapper, options, + "HTTP invalid response format (folding header at the start)!"); + goto out; } + /* Trim the first line if it is not the last line. */ + php_stream_http_response_header_trim(http_header_line, &http_header_line_length); } - - { - zval http_header; - ZVAL_STRINGL(&http_header, http_header_line, http_header_line_length); - zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header); + if (last_line) { + /* For the last line the last header line must be NULL. */ + ZEND_ASSERT(last_header_line_str == NULL); + break; } + /* Save current line as the last line so it gets parsed in the next round. */ + last_header_line_str = zend_string_init(http_header_line, http_header_line_length, 0); } else { break; } } - if (!reqok || (location[0] != '\0' && follow_location)) { - if (!follow_location || (((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) && redirect_max <= 1)) { + /* If the stream was closed early, we still want to process the last line to keep BC. */ + if (last_header_line_str != NULL) { + php_stream_http_response_headers_parse(wrapper, stream, context, options, + last_header_line_str, NULL, NULL, response_code, response_header, &header_info); + } + + if (!reqok || (header_info.location != NULL && header_info.follow_location)) { + if (!header_info.follow_location || (((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) && redirect_max <= 1)) { goto out; } - if (location[0] != '\0') - php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0); + if (header_info.location != NULL) + php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, header_info.location, 0); php_stream_close(stream); stream = NULL; - if (transfer_encoding) { - php_stream_filter_free(transfer_encoding); - transfer_encoding = NULL; + if (header_info.transfer_encoding) { + php_stream_filter_free(header_info.transfer_encoding); + header_info.transfer_encoding = NULL; } - if (location[0] != '\0') { + if (header_info.location != NULL) { - char new_path[HTTP_HEADER_BLOCK_SIZE]; - char loc_path[HTTP_HEADER_BLOCK_SIZE]; + char *new_path = NULL; - *new_path='\0'; - if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && - strncasecmp(location, "https://", sizeof("https://")-1) && - strncasecmp(location, "ftp://", sizeof("ftp://")-1) && - strncasecmp(location, "ftps://", sizeof("ftps://")-1))) + if (strlen(header_info.location) < 8 || + (strncasecmp(header_info.location, "http://", sizeof("http://")-1) && + strncasecmp(header_info.location, "https://", sizeof("https://")-1) && + strncasecmp(header_info.location, "ftp://", sizeof("ftp://")-1) && + strncasecmp(header_info.location, "ftps://", sizeof("ftps://")-1))) { - if (*location != '/') { - if (*(location+1) != '\0' && resource->path) { + char *loc_path = NULL; + if (*header_info.location != '/') { + if (*(header_info.location+1) != '\0' && resource->path) { char *s = strrchr(ZSTR_VAL(resource->path), '/'); if (!s) { s = ZSTR_VAL(resource->path); @@ -893,29 +1064,35 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (resource->path && ZSTR_VAL(resource->path)[0] == '/' && ZSTR_VAL(resource->path)[1] == '\0') { - snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", ZSTR_VAL(resource->path), location); + spprintf(&loc_path, 0, "%s%s", ZSTR_VAL(resource->path), header_info.location); } else { - snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", ZSTR_VAL(resource->path), location); + spprintf(&loc_path, 0, "%s/%s", ZSTR_VAL(resource->path), header_info.location); } } else { - snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location); + spprintf(&loc_path, 0, "/%s", header_info.location); } } else { - strlcpy(loc_path, location, sizeof(loc_path)); + loc_path = header_info.location; + header_info.location = NULL; } if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { - snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", ZSTR_VAL(resource->scheme), ZSTR_VAL(resource->host), resource->port, loc_path); + spprintf(&new_path, 0, "%s://%s:%d%s", ZSTR_VAL(resource->scheme), + ZSTR_VAL(resource->host), resource->port, loc_path); } else { - snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", ZSTR_VAL(resource->scheme), ZSTR_VAL(resource->host), loc_path); + spprintf(&new_path, 0, "%s://%s%s", ZSTR_VAL(resource->scheme), + ZSTR_VAL(resource->host), loc_path); } + efree(loc_path); } else { - strlcpy(new_path, location, sizeof(new_path)); + new_path = header_info.location; + header_info.location = NULL; } php_url_free(resource); /* check for invalid redirection URLs */ if ((resource = php_url_parse(new_path)) == NULL) { php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path); + efree(new_path); goto out; } @@ -927,6 +1104,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, while (s < e) { \ if (iscntrl(*s)) { \ php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path); \ + efree(new_path); \ goto out; \ } \ s++; \ @@ -949,6 +1127,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, stream = php_stream_url_wrap_http_ex( wrapper, new_path, mode, options, opened_path, context, --redirect_max, new_flags, response_header STREAMS_CC); + efree(new_path); } else { php_stream_wrapper_log_error(wrapper, options, "HTTP request failed! %s", tmp_line); } @@ -961,6 +1140,10 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, efree(http_header_line); } + if (header_info.location != NULL) { + efree(header_info.location); + } + if (resource) { php_url_free(resource); } @@ -969,7 +1152,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (header_init) { ZVAL_COPY(&stream->wrapperdata, response_header); } - php_stream_notify_progress_init(context, 0, file_size); + php_stream_notify_progress_init(context, 0, header_info.file_size); /* Restore original chunk size now that we're done with headers */ if (options & STREAM_WILL_CAST) @@ -985,8 +1168,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* restore mode */ strlcpy(stream->mode, mode, sizeof(stream->mode)); - if (transfer_encoding) { - php_stream_filter_append(&stream->readfilters, transfer_encoding); + if (header_info.transfer_encoding) { + php_stream_filter_append(&stream->readfilters, header_info.transfer_encoding); } /* It's possible that the server already sent in more data than just the headers. diff --git a/ext/standard/tests/array/gh17977.phpt b/ext/standard/tests/array/gh17977.phpt new file mode 100644 index 0000000000000..4a4f344dc4759 --- /dev/null +++ b/ext/standard/tests/array/gh17977.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_any() / array_all() leak +--DESCRIPTION-- +Found in GH-16831#issuecomment-2700410631 +--FILE-- + 1], static fn () => true)); +var_dump(array_all([$key => 1], static fn () => false)); + +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/standard/tests/file/bug72666_variation3.phpt b/ext/standard/tests/file/bug72666_variation3.phpt index a491640c4f746..7937bd904ad7d 100644 --- a/ext/standard/tests/file/bug72666_variation3.phpt +++ b/ext/standard/tests/file/bug72666_variation3.phpt @@ -5,23 +5,11 @@ Bug #72666 (stat cache clearing inconsistent - plain wrapper) $filename = __DIR__ . '/bug72666_variation3.txt'; file_put_contents($filename, "test"); -$fd = fopen($filename, "r"); -$atime1 = fileatime($filename); -sleep(1); -var_dump(fread($fd, 4)); -$atime2 = fileatime($filename); $mtime1 = filemtime($filename); -fclose($fd); $fd = fopen($filename, "w"); sleep(1); var_dump(fwrite($fd, "data")); $mtime2 = filemtime($filename); -if (substr(PHP_OS, 0, 3) == 'WIN') { - // Windows do not hundle atime - var_dump($atime2 == $atime1); -} else { - var_dump($atime2 > $atime1); -} var_dump($mtime2 > $mtime1); ?> --CLEAN-- @@ -29,7 +17,5 @@ var_dump($mtime2 > $mtime1); unlink(__DIR__ . '/bug72666_variation3.txt'); ?> --EXPECT-- -string(4) "test" int(4) bool(true) -bool(true) diff --git a/ext/standard/tests/http/bug47021.phpt b/ext/standard/tests/http/bug47021.phpt index 326eceb687a52..168721f4ec1b6 100644 --- a/ext/standard/tests/http/bug47021.phpt +++ b/ext/standard/tests/http/bug47021.phpt @@ -70,23 +70,27 @@ do_test(1, true); echo "\n"; ?> ---EXPECT-- +--EXPECTF-- + Type='text/plain' Hello -Size=5 -World + +Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s + Type='text/plain' Hello -Size=5 -World + +Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s + Type='text/plain' Hello -Size=5 -World + +Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s + Type='text/plain' Hello -Size=5 -World + +Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s diff --git a/ext/standard/tests/http/bug75535.phpt b/ext/standard/tests/http/bug75535.phpt index 27249c3fa18ec..94348d1a027aa 100644 --- a/ext/standard/tests/http/bug75535.phpt +++ b/ext/standard/tests/http/bug75535.phpt @@ -14,27 +14,14 @@ $responses = array( ['pid' => $pid, 'uri' => $uri] = http_server($responses, $output); -var_dump(http_get_last_response_headers()); - var_dump(file_get_contents($uri)); var_dump($http_response_header); -var_dump(http_get_last_response_headers()); http_server_kill($pid); -?> --EXPECT-- -NULL string(0) "" -array(2) { - [0]=> - string(15) "HTTP/1.0 200 Ok" - [1]=> - string(14) "Content-Length" -} -array(2) { +array(1) { [0]=> string(15) "HTTP/1.0 200 Ok" - [1]=> - string(14) "Content-Length" } diff --git a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt new file mode 100644 index 0000000000000..744cff9cc72f2 --- /dev/null +++ b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt @@ -0,0 +1,58 @@ +--TEST-- +GHSA-52jp-hrpf-2jff: HTTP stream wrapper truncate redirect location to 1024 bytes (success) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + $loc = str_repeat("y", 8000); + fwrite($conn, "HTTP/1.0 301 Ok\r\nContent-Type: text/html;\r\nLocation: $loc\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + case STREAM_NOTIFY_REDIRECTED: + echo "Redirected: "; + var_dump($message); + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html; +Redirected: string(8000) "%s" + +Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: %s +string(0) "" +array(3) { + [0]=> + string(15) "HTTP/1.0 301 Ok" + [1]=> + string(24) "Content-Type: text/html;" + [2]=> + string(8010) "Location: %s" +} diff --git a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt new file mode 100644 index 0000000000000..bc71fd4e41167 --- /dev/null +++ b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt @@ -0,0 +1,55 @@ +--TEST-- +GHSA-52jp-hrpf-2jff: HTTP stream wrapper truncate redirect location to 1024 bytes (over limit) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + $loc = str_repeat("y", 9000); + fwrite($conn, "HTTP/1.0 301 Ok\r\nContent-Type: text/html;\r\nLocation: $loc\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + case STREAM_NOTIFY_REDIRECTED: + echo "Redirected: "; + var_dump($message); + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html; + +Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP Location header size is over the limit of 8182 bytes in %s +string(0) "" +array(2) { + [0]=> + string(15) "HTTP/1.0 301 Ok" + [1]=> + string(24) "Content-Type: text/html;" +} diff --git a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt new file mode 100644 index 0000000000000..c40123560ef1e --- /dev/null +++ b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt @@ -0,0 +1,65 @@ +--TEST-- +GHSA-hgf5-96fm-v528: Stream HTTP wrapper header check might omit basic auth header (incorrect inside pos) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + $result = fread($conn, 1024); + $encoded_result = base64_encode($result); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html; charset=utf-8\r\n\r\n$encoded_result\r\n"); + +CODE; + +$clientCode = <<<'CODE' + $opts = [ + "http" => [ + "method" => "GET", + "header" => "Cookie: foo=bar\nauthorization:x\r\n" + ] + ]; + $ctx = stream_context_create($opts); + var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx)))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +array(7) { + [0]=> + string(14) "GET / HTTP/1.1" + [1]=> + string(33) "Authorization: Basic dXNlcjpwd2Q=" + [2]=> + string(21) "Host: 127.0.0.1:%d" + [3]=> + string(17) "Connection: close" + [4]=> + string(31) "Cookie: foo=bar +authorization:x" + [5]=> + string(0) "" + [6]=> + string(0) "" +} +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(38) "Content-Type: text/html; charset=utf-8" +} diff --git a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt new file mode 100644 index 0000000000000..37a47df060a1c --- /dev/null +++ b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt @@ -0,0 +1,62 @@ +--TEST-- +GHSA-hgf5-96fm-v528: Header parser of http stream wrapper does not handle folded headers (correct start pos) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + $result = fread($conn, 1024); + $encoded_result = base64_encode($result); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html; charset=utf-8\r\n\r\n$encoded_result\r\n"); + +CODE; + +$clientCode = <<<'CODE' + $opts = [ + "http" => [ + "method" => "GET", + "header" => "Authorization: Bearer x\r\n" + ] + ]; + $ctx = stream_context_create($opts); + var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx)))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +array(6) { + [0]=> + string(14) "GET / HTTP/1.1" + [1]=> + string(21) "Host: 127.0.0.1:%d" + [2]=> + string(17) "Connection: close" + [3]=> + string(23) "Authorization: Bearer x" + [4]=> + string(0) "" + [5]=> + string(0) "" +} +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(38) "Content-Type: text/html; charset=utf-8" +} diff --git a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt new file mode 100644 index 0000000000000..6c84679ff63bd --- /dev/null +++ b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt @@ -0,0 +1,64 @@ +--TEST-- +GHSA-hgf5-96fm-v528: Header parser of http stream wrapper does not handle folded headers (correct middle pos) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + $result = fread($conn, 1024); + $encoded_result = base64_encode($result); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html; charset=utf-8\r\n\r\n$encoded_result\r\n"); + +CODE; + +$clientCode = <<<'CODE' + $opts = [ + "http" => [ + "method" => "GET", + "header" => "Cookie: x=y\r\nAuthorization: Bearer x\r\n" + ] + ]; + $ctx = stream_context_create($opts); + var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx)))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +array(7) { + [0]=> + string(14) "GET / HTTP/1.1" + [1]=> + string(21) "Host: 127.0.0.1:%d" + [2]=> + string(17) "Connection: close" + [3]=> + string(11) "Cookie: x=y" + [4]=> + string(23) "Authorization: Bearer x" + [5]=> + string(0) "" + [6]=> + string(0) "" +} +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(38) "Content-Type: text/html; charset=utf-8" +} diff --git a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt new file mode 100644 index 0000000000000..bb7945ce62d0e --- /dev/null +++ b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt @@ -0,0 +1,51 @@ +--TEST-- +GHSA-pcmh-g36c-qc44: Header parser of http stream wrapper does not verify header name and colon (colon) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html\r\nWrong-Header\r\nGood-Header: test\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html + +Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s +bool(false) +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(23) "Content-Type: text/html" +} diff --git a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt new file mode 100644 index 0000000000000..1d0e4fa70a2c9 --- /dev/null +++ b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt @@ -0,0 +1,51 @@ +--TEST-- +GHSA-pcmh-g36c-qc44: Header parser of http stream wrapper does not verify header name and colon (name) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html\r\nWrong-Header : test\r\nGood-Header: test\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html + +Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid response format (space in header name)! in %s +bool(false) +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(23) "Content-Type: text/html" +} diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt new file mode 100644 index 0000000000000..f935b5a02ca94 --- /dev/null +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt @@ -0,0 +1,49 @@ +--TEST-- +GHSA-v8xr-gpvj-cx9g: Header parser of http stream wrapper does not handle folded headers (single) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html;\r\n charset=utf-8\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html; charset=utf-8 +string(4) "body" +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(38) "Content-Type: text/html; charset=utf-8" +} diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt new file mode 100644 index 0000000000000..078d605b6718f --- /dev/null +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt @@ -0,0 +1,51 @@ +--TEST-- +GHSA-v8xr-gpvj-cx9g: Header parser of http stream wrapper does not handle folded headers (multiple) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html;\r\nCustom-Header: somevalue;\r\n param1=value1; \r\n param2=value2\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html; +string(4) "body" +array(3) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(24) "Content-Type: text/html;" + [2]=> + string(54) "Custom-Header: somevalue; param1=value1; param2=value2" +} diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt new file mode 100644 index 0000000000000..ad5ddc879cead --- /dev/null +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt @@ -0,0 +1,49 @@ +--TEST-- +GHSA-v8xr-gpvj-cx9g: Header parser of http stream wrapper does not handle folded headers (empty) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\nContent-Type: text/html;\r\n \r\n charset=utf-8\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Found the mime-type: text/html; charset=utf-8 +string(4) "body" +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(38) "Content-Type: text/html; charset=utf-8" +} diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt new file mode 100644 index 0000000000000..d0396e819fbd3 --- /dev/null +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt @@ -0,0 +1,48 @@ +--TEST-- +GHSA-v8xr-gpvj-cx9g: Header parser of http stream wrapper does not handle folded headers (first line) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\n Content-Type: text/html;\r\n \r\n charset=utf-8\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- + +Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid response format (folding header at the start)! in %s +bool(false) +array(1) { + [0]=> + string(15) "HTTP/1.0 200 Ok" +} diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt new file mode 100644 index 0000000000000..037d2002cc537 --- /dev/null +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt @@ -0,0 +1,48 @@ +--TEST-- +GHSA-v8xr-gpvj-cx9g: Header parser of http stream wrapper does not handle folded headers (CR before header name) +--FILE-- + [ + "tcp_nodelay" => true + ] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + + phpt_notify(message:"server-accepted"); + + fwrite($conn, "HTTP/1.0 200 Ok\r\n\rIgnored: ignored\r\n\r\nbody\r\n"); +CODE; + +$clientCode = <<<'CODE' + function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { + switch($notification_code) { + case STREAM_NOTIFY_MIME_TYPE_IS: + echo "Found the mime-type: ", $message, PHP_EOL; + break; + } + } + + $ctx = stream_context_create(); + stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); + var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); + var_dump($http_response_header); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- + +Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid header name (cannot start with CR character)! in %s +bool(false) +array(1) { + [0]=> + string(15) "HTTP/1.0 200 Ok" +} diff --git a/ext/standard/tests/http/http_response_header_05.phpt b/ext/standard/tests/http/http_response_header_05.phpt deleted file mode 100644 index d2a7800f42850..0000000000000 --- a/ext/standard/tests/http/http_response_header_05.phpt +++ /dev/null @@ -1,41 +0,0 @@ ---TEST-- -$http_reponse_header (whitespace-only "header") ---SKIPIF-- - ---INI-- -allow_url_fopen=1 ---FILE-- - $pid, 'uri' => $uri] = http_server($responses, $output); - -var_dump(http_get_last_response_headers()); - -$f = file_get_contents($uri); -var_dump($f); -var_dump($http_response_header); -var_dump(http_get_last_response_headers()); - -http_server_kill($pid); - -?> ---EXPECT-- -NULL -string(4) "Body" -array(2) { - [0]=> - string(15) "HTTP/1.0 200 Ok" - [1]=> - string(0) "" -} -array(2) { - [0]=> - string(15) "HTTP/1.0 200 Ok" - [1]=> - string(0) "" -} diff --git a/ext/xml/tests/toffset_bounds.phpt b/ext/xml/tests/toffset_bounds.phpt new file mode 100644 index 0000000000000..5a3fd22f86cd7 --- /dev/null +++ b/ext/xml/tests/toffset_bounds.phpt @@ -0,0 +1,42 @@ +--TEST-- +XML_OPTION_SKIP_TAGSTART bounds +--EXTENSIONS-- +xml +--FILE-- +"; +$parser = xml_parser_create(); +xml_parser_set_option($parser, XML_OPTION_SKIP_TAGSTART, 100); +$res = xml_parse_into_struct($parser,$sample,$vals,$index); +var_dump($vals); +?> +--EXPECT-- +array(3) { + [0]=> + array(3) { + ["tag"]=> + string(0) "" + ["type"]=> + string(4) "open" + ["level"]=> + int(1) + } + [1]=> + array(3) { + ["tag"]=> + string(0) "" + ["type"]=> + string(8) "complete" + ["level"]=> + int(2) + } + [2]=> + array(3) { + ["tag"]=> + string(0) "" + ["type"]=> + string(5) "close" + ["level"]=> + int(1) + } +} diff --git a/ext/xml/xml.c b/ext/xml/xml.c index fb1aa2f74bbf7..8394bbf3cb31b 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -663,9 +663,11 @@ void xml_startElementHandler(void *userData, const XML_Char *name, const XML_Cha array_init(&tag); array_init(&atr); - xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset); + char *skipped_tag_name = SKIP_TAGSTART(ZSTR_VAL(tag_name)); - add_assoc_string(&tag, "tag", SKIP_TAGSTART(ZSTR_VAL(tag_name))); /* cast to avoid gcc-warning */ + xml_add_to_info(parser, skipped_tag_name); + + add_assoc_string(&tag, "tag", skipped_tag_name); add_assoc_string(&tag, "type", "open"); add_assoc_long(&tag, "level", parser->level); @@ -747,12 +749,14 @@ void xml_endElementHandler(void *userData, const XML_Char *name) add_assoc_string(zv, "type", "complete"); } } else { - xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset); + char *skipped_tag_name = SKIP_TAGSTART(ZSTR_VAL(tag_name)); + + xml_add_to_info(parser, skipped_tag_name); zval *data = xml_get_separated_data(parser); if (EXPECTED(data)) { array_init(&tag); - add_assoc_string(&tag, "tag", SKIP_TAGSTART(ZSTR_VAL(tag_name))); /* cast to avoid gcc-warning */ + add_assoc_string(&tag, "tag", skipped_tag_name); add_assoc_string(&tag, "type", "close"); add_assoc_long(&tag, "level", parser->level); zend_hash_next_index_insert(Z_ARRVAL_P(data), &tag); diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 083cd33cc6cd4..d0a3673c89423 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -113,10 +113,12 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot) { zval *retval = NULL; - xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name); + xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name); if (hnd == NULL) { retval = zend_std_get_property_ptr_ptr(object, name, type, cache_slot); + } else { + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; } return retval; diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index d215bbfa457a1..dbad83fb0e843 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -703,6 +703,15 @@ void * zend_test_custom_realloc(void * ptr, size_t len ZEND_FILE_LINE_DC ZEND_FI return _zend_mm_realloc(ZT_G(zend_orig_heap), ptr, len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC); } +static void zend_test_reset_heap(zend_zend_test_globals *zend_test_globals) +{ + if (zend_test_globals->zend_test_heap) { + free(zend_test_globals->zend_test_heap); + zend_test_globals->zend_test_heap = NULL; + zend_mm_set_heap(zend_test_globals->zend_orig_heap); + } +} + static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM) { if (new_value == NULL) { @@ -724,10 +733,8 @@ static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM) ); ZT_G(zend_orig_heap) = zend_mm_get_heap(); zend_mm_set_heap(ZT_G(zend_test_heap)); - } else if (ZT_G(zend_test_heap)) { - free(ZT_G(zend_test_heap)); - ZT_G(zend_test_heap) = NULL; - zend_mm_set_heap(ZT_G(zend_orig_heap)); + } else { + zend_test_reset_heap(ZEND_MODULE_GLOBALS_BULK(zend_test)); } return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } @@ -1397,6 +1404,7 @@ static PHP_GINIT_FUNCTION(zend_test) static PHP_GSHUTDOWN_FUNCTION(zend_test) { zend_test_observer_gshutdown(zend_test_globals); + zend_test_reset_heap(zend_test_globals); } PHP_MINFO_FUNCTION(zend_test) diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index e9b560ab1df61..3b2fe0bc366c2 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -889,6 +889,8 @@ static zval *php_zip_get_property_ptr_ptr(zend_object *object, zend_string *name zval *retval = NULL; zip_prop_handler *hnd = NULL; + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + obj = php_zip_fetch_object(object); if (obj->prop_handler != NULL) { diff --git a/main/php_version.h b/main/php_version.h index 2f3f61ddbf1e0..f2c1342724919 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 4 -#define PHP_RELEASE_VERSION 5 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.4.5-dev" -#define PHP_VERSION_ID 80405 +#define PHP_RELEASE_VERSION 6 +#define PHP_EXTRA_VERSION "" +#define PHP_VERSION "8.4.6" +#define PHP_VERSION_ID 80406 diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4 index c385e289a70ee..2bb5ed4df4da4 100644 --- a/sapi/embed/config.m4 +++ b/sapi/embed/config.m4 @@ -11,7 +11,10 @@ if test "$PHP_EMBED" != "no"; then AS_CASE([$PHP_EMBED], [yes|shared], [ LIBPHP_CFLAGS="-shared" - PHP_EMBED_TYPE=shared + AS_CASE(["$host_alias"], [*darwin*], [ + SAPI_SHARED="libs/libphp.dylib" + PHP_EMBED_TYPE=shared-dylib + ], [PHP_EMBED_TYPE=shared]) INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0755 $SAPI_SHARED \$(INSTALL_ROOT)\$(orig_libdir)" ], [static], [ diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index d93459b4ea370..fb02a3e191775 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -93,7 +93,21 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */ if (!strcmp(name, "extension") && *value) { zval zv; zend_interned_strings_switch_storage(0); + +#if ZEND_RC_DEBUG + bool orig_rc_debug = zend_rc_debug; + /* Loading extensions after php_module_startup() breaks some invariants. + * For instance, it will update the refcount of persistent strings, + * which is normally not allowed at this stage. */ + zend_rc_debug = false; +#endif + php_dl(value, MODULE_PERSISTENT, &zv, 1); + +#if ZEND_RC_DEBUG + zend_rc_debug = orig_rc_debug; +#endif + zend_interned_strings_switch_storage(1); return Z_TYPE(zv) == IS_TRUE ? FPM_PHP_INI_EXTENSION_LOADED : FPM_PHP_INI_EXTENSION_FAILED; } diff --git a/sapi/fuzzer/fuzzer-json.c b/sapi/fuzzer/fuzzer-json.c index 930f136a47236..78c8505c2f1dc 100644 --- a/sapi/fuzzer/fuzzer-json.c +++ b/sapi/fuzzer/fuzzer-json.c @@ -15,8 +15,6 @@ +----------------------------------------------------------------------+ */ - - #include "fuzzer.h" #include "Zend/zend.h" @@ -31,14 +29,15 @@ #include "ext/json/php_json_parser.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - char *data = malloc(Size+1); - memcpy(data, Data, Size); - data[Size] = '\0'; - if (fuzzer_request_startup() == FAILURE) { + if (fuzzer_request_startup() == FAILURE){ return 0; } + char *data = malloc(Size + 1); + memcpy(data, Data, Size); + data[Size] = '\0'; + for (int option = 0; option <=1; ++option) { zval result; php_json_parser parser; diff --git a/sapi/fuzzer/fuzzer-mbregex.c b/sapi/fuzzer/fuzzer-mbregex.c index 451b19d99e310..f96e593ba8d24 100644 --- a/sapi/fuzzer/fuzzer-mbregex.c +++ b/sapi/fuzzer/fuzzer-mbregex.c @@ -30,15 +30,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { #ifdef HAVE_MBREGEX - char *args[2]; - char *data = malloc(Size+1); - memcpy(data, Data, Size); - data[Size] = '\0'; if (fuzzer_request_startup() == FAILURE) { return 0; } + char *args[2]; + char *data = malloc(Size+1); + memcpy(data, Data, Size); + data[Size] = '\0'; + fuzzer_setup_dummy_frame(); args[0] = data; diff --git a/sapi/fuzzer/fuzzer-unserialize.c b/sapi/fuzzer/fuzzer-unserialize.c index 023a19fbd08d3..8a889883a97d8 100644 --- a/sapi/fuzzer/fuzzer-unserialize.c +++ b/sapi/fuzzer/fuzzer-unserialize.c @@ -30,14 +30,15 @@ #include "ext/standard/php_var.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - unsigned char *orig_data = malloc(Size+1); - memcpy(orig_data, Data, Size); - orig_data[Size] = '\0'; if (fuzzer_request_startup() == FAILURE) { return 0; } + unsigned char *orig_data = malloc(Size+1); + memcpy(orig_data, Data, Size); + orig_data[Size] = '\0'; + fuzzer_setup_dummy_frame(); { diff --git a/sapi/fuzzer/fuzzer-unserializehash.c b/sapi/fuzzer/fuzzer-unserializehash.c index 90d874aba88cc..447e95d0ee815 100644 --- a/sapi/fuzzer/fuzzer-unserializehash.c +++ b/sapi/fuzzer/fuzzer-unserializehash.c @@ -34,15 +34,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t FullSize) { } ++Start; + if (fuzzer_request_startup() == FAILURE) { + return 0; + } + size_t Size = (Data + FullSize) - Start; unsigned char *orig_data = malloc(Size+1); memcpy(orig_data, Start, Size); orig_data[Size] = '\0'; - if (fuzzer_request_startup() == FAILURE) { - return 0; - } - fuzzer_setup_dummy_frame(); {