diff --git a/ext/intl/converter/converter.cpp b/ext/intl/converter/converter.cpp index 051f3ca8bd3a..430d58c8f025 100644 --- a/ext/intl/converter/converter.cpp +++ b/ext/intl/converter/converter.cpp @@ -167,9 +167,9 @@ static void php_converter_append_toUnicode_target(zval *val, UConverterToUnicode if (lval > 0xFFFF) { /* Supplemental planes U+010000 - U+10FFFF */ if (TARGET_CHECK(args, 2)) { - /* TODO: Find the ICU call which does this properly */ - *(args->target++) = (UChar)(((lval - 0x10000) >> 10) | 0xD800); - *(args->target++) = (UChar)(((lval - 0x10000) & 0x3FF) | 0xDC00); + int32_t offset = 0; + U16_APPEND_UNSAFE(args->target, offset, lval); + args->target += offset; } return; } diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 1d43946f41d3..bce57b0ab052 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -720,9 +720,6 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c if (ret == FAIL) { COPY_CLIENT_ERROR(&set->error_info, row_packet.error_info); - } else { - /* libmysql's documentation says it should be so for SELECT statements */ - UPSERT_STATUS_SET_AFFECTED_ROWS(conn->upsert_status, set->row_count); } DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", ret == PASS? "PASS":"FAIL", @@ -1002,18 +999,11 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int } } if (flags & MYSQLND_FETCH_ASSOC) { - /* zend_hash_quick_update needs length + trailing zero */ - /* QQ: Error handling ? */ - /* - zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether - the index is a numeric and convert it to it. This however means constant - hashing of the column name, which is not needed as it can be precomputed. - */ Z_TRY_ADDREF_P(data); - if (meta->fields[i].is_numeric == FALSE) { - zend_hash_update(row_ht, meta->fields[i].sname, data); + if (field->is_numeric == FALSE) { + zend_hash_update(row_ht, field->sname, data); } else { - zend_hash_index_update(row_ht, meta->fields[i].num_key, data); + zend_hash_index_update(row_ht, field->num_key, data); } } diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 1c7fb4073569..012edd194e31 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -1095,6 +1095,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (UNEXPECTED(!jit_extension) || UNEXPECTED(!(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE))) { if (execute_data->prev_execute_data != prev_execute_data) { + stop = ZEND_JIT_TRACE_STOP_RETURN; + } else { stop = ZEND_JIT_TRACE_STOP_INTERPRETER; } break; diff --git a/ext/opcache/tests/jit/gh21746.inc b/ext/opcache/tests/jit/gh21746.inc new file mode 100644 index 000000000000..b118625484d0 --- /dev/null +++ b/ext/opcache/tests/jit/gh21746.inc @@ -0,0 +1,16 @@ + ''; + $e = fn() => ''; + $f = fn() => ''; + $g = fn() => ''; + return '' + .LR::p(null, '', null, [], '') + .LR::hbbch([null], $d) + .LR::hbbch([null], $e) + .LR::hbbch([null], $f) + .LR::hbbch([null], $g); +}; diff --git a/ext/opcache/tests/jit/gh21746.phpt b/ext/opcache/tests/jit/gh21746.phpt new file mode 100644 index 000000000000..29b3be778be7 --- /dev/null +++ b/ext/opcache/tests/jit/gh21746.phpt @@ -0,0 +1,112 @@ +--TEST-- +GH-21746: Segfault with tracing JIT on 2nd call of eval'd closure +--CREDITS-- +theodorejb +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=tracing +--FILE-- + $_) { if ($i === 0) break; } + return $result; + } + public static function hbbch(array $positional, ?\Closure $cb): string { + if ($cb && is_array($positional[0] ?? null)) foreach ($positional[0] as $v) $cb($v); + return ''; + } +} + +$renderFile = __DIR__ . '/gh21746.inc'; + +// prevent JITing $renderFile +ini_set('opcache.file_update_protection', 100); +touch($renderFile); + +$renderer = require $renderFile; + +for ($r = 0; $r < 70; $r++) { + echo "Render $r..."; + $renderer(); + echo "OK\n"; +} + +?> +==DONE== +--EXPECT-- +Render 0...OK +Render 1...OK +Render 2...OK +Render 3...OK +Render 4...OK +Render 5...OK +Render 6...OK +Render 7...OK +Render 8...OK +Render 9...OK +Render 10...OK +Render 11...OK +Render 12...OK +Render 13...OK +Render 14...OK +Render 15...OK +Render 16...OK +Render 17...OK +Render 18...OK +Render 19...OK +Render 20...OK +Render 21...OK +Render 22...OK +Render 23...OK +Render 24...OK +Render 25...OK +Render 26...OK +Render 27...OK +Render 28...OK +Render 29...OK +Render 30...OK +Render 31...OK +Render 32...OK +Render 33...OK +Render 34...OK +Render 35...OK +Render 36...OK +Render 37...OK +Render 38...OK +Render 39...OK +Render 40...OK +Render 41...OK +Render 42...OK +Render 43...OK +Render 44...OK +Render 45...OK +Render 46...OK +Render 47...OK +Render 48...OK +Render 49...OK +Render 50...OK +Render 51...OK +Render 52...OK +Render 53...OK +Render 54...OK +Render 55...OK +Render 56...OK +Render 57...OK +Render 58...OK +Render 59...OK +Render 60...OK +Render 61...OK +Render 62...OK +Render 63...OK +Render 64...OK +Render 65...OK +Render 66...OK +Render 67...OK +Render 68...OK +Render 69...OK +==DONE==