From f31e4e6068f0659f25c9be15da82a67e9c45a137 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 30 Apr 2026 15:35:18 +0100 Subject: [PATCH 1/4] ext/phar: convert phar_open_executed_filename() to use zend_string for alias (#21916) --- ext/phar/phar.c | 8 +++++--- ext/phar/phar_internal.h | 2 +- ext/phar/phar_object.c | 17 +++++++++-------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index cd363fbd88ee..d3b14b65504f 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2252,7 +2252,7 @@ zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_st * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(const char *alias, size_t alias_len, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(const zend_string *alias, char **error) /* {{{ */ { *error = NULL; @@ -2263,7 +2263,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(const cha return FAILURE; } - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias_cstr, alias_len, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { return SUCCESS; } @@ -2292,7 +2294,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(const cha fname = actual; } - zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, error); + zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias_cstr, alias_len, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 7a923fd15e18..30018986f1f6 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -409,7 +409,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(const char *alias, size_t alias_len, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(const zend_string *alias, char **error); zend_result phar_free_alias(const phar_archive_data *phar); phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error); zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, const char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 00a5ebf3058f..32c7d2b866c7 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -549,8 +549,8 @@ PHP_METHOD(Phar, webPhar) zval *mimeoverride = NULL; zend_fcall_info rewrite_fci = {0}; zend_fcall_info_cache rewrite_fcc; - char *alias = NULL, *error, *index_php = NULL, *ru = NULL; - size_t alias_len = 0, free_pathinfo = 0; + char *error, *index_php = NULL, *ru = NULL; + size_t free_pathinfo = 0; zend_string *f404 = NULL; size_t ru_len = 0; char *fname, *path_info, *mime_type = NULL, *entry, *pt; @@ -562,14 +562,15 @@ PHP_METHOD(Phar, webPhar) phar_entry_info *info = NULL; size_t sapi_mod_name_len = strlen(sapi_module.name); phar_action_status status = PHAR_ACT_DO_EXIT; + zend_string *alias = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!S!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!s!S!af!", &alias, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) { + if (phar_open_executed_filename(alias, &error) != SUCCESS) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error); @@ -947,17 +948,17 @@ PHP_METHOD(Phar, createDefaultStub) /* {{{ Reads the currently executed file (a phar) and registers its manifest */ PHP_METHOD(Phar, mapPhar) { - char *alias = NULL, *error; - size_t alias_len = 0; + zend_string *alias = NULL; + char *error; zend_long dataoffset = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!l", &alias, &alias_len, &dataoffset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!l", &alias, &dataoffset) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_executed_filename(alias, alias_len, &error) == SUCCESS); + RETVAL_BOOL(phar_open_executed_filename(alias, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); From b04136ee71db97c358ceb49eb5347eb5a05e03f6 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 30 Apr 2026 15:35:51 +0100 Subject: [PATCH 2/4] ext/phar: convert phar_open_from_filename() to use zend_string for alias (#21917) --- ext/phar/phar.c | 12 +++++++----- ext/phar/phar_internal.h | 2 +- ext/phar/phar_object.c | 12 ++++++------ ext/phar/stream.c | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index d3b14b65504f..ef25e9c3192e 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -131,7 +131,7 @@ static void phar_split_cache_list(void) /* {{{ */ len = strlen(key); } - if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, &phar, NULL)) { phar->phar_pos = i++; php_stream_close(phar->fp); phar->fp = NULL; @@ -1507,7 +1507,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(z * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_from_filename(char *fname, size_t fname_len, const zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual; @@ -1521,7 +1521,9 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *a is_data = true; } - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, pphar, error) == SUCCESS) { + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + if (phar_open_parsed_phar(fname, fname_len, alias_cstr, alias_len, is_data, options, pphar, error) == SUCCESS) { return SUCCESS; } else if (error && *error) { return FAILURE; @@ -1549,7 +1551,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *a fname_len = ZSTR_LEN(actual); } - zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error); + zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias_cstr, alias_len, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -3158,7 +3160,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) return phar_orig_compile_file(file_handle, type); } if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) { - if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, &phar, NULL)) { if (phar->is_zip || phar->is_tar) { zend_file_handle f; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 30018986f1f6..5054699a8cbd 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -406,7 +406,7 @@ void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_open_from_filename(char *fname, size_t fname_len, const zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(const zend_string *alias, char **error); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 32c7d2b866c7..66d543732407 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -970,16 +970,16 @@ PHP_METHOD(Phar, mapPhar) PHP_METHOD(Phar, loadPhar) { zend_string *fname; - char *alias = NULL, *error; - size_t alias_len = 0; + zend_string *alias = NULL; + char *error; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|s!", &fname, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &fname, &alias) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, &error) == SUCCESS); + RETVAL_BOOL(phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, REPORT_ERRORS, NULL, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -1266,7 +1266,7 @@ PHP_METHOD(Phar, unlinkArchive) RETURN_THROWS(); } - if (FAILURE == phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 0, REPORT_ERRORS, &phar, &error)) { + if (FAILURE == phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, REPORT_ERRORS, &phar, &error)) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", ZSTR_VAL(fname), error); efree(error); @@ -4416,7 +4416,7 @@ PHP_METHOD(PharFileInfo, __construct) RETURN_THROWS(); } - if (phar_open_from_filename(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + if (phar_open_from_filename(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, REPORT_ERRORS, &phar_data, &error) == FAILURE) { zend_string_release_ex(arch, false); efree(entry); if (error) { diff --git a/ext/phar/stream.c b/ext/phar/stream.c index f9d19a04122a..29ce9ea9077d 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -137,7 +137,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const return NULL; } } else { - if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, options, NULL, &error) == FAILURE) + if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, options, NULL, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { From ff1bb13315740a80c8072acb91d82ee3aed86c9d Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 30 Apr 2026 15:52:19 +0200 Subject: [PATCH 3/4] ASN1_STRING has been made opaque in OpenSSL 4 --- ext/openssl/openssl_backend_common.c | 10 +++++----- ext/openssl/xp_ssl.c | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 222053984916..5aa8d246177e 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -108,7 +108,7 @@ void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, void php_openssl_add_assoc_asn1_string(zval * val, char * key, ASN1_STRING * str) { - add_assoc_stringl(val, key, (char *)str->data, str->length); + add_assoc_stringl(val, key, (const char *)ASN1_STRING_get0_data(str), ASN1_STRING_length(str)); } time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr) @@ -140,12 +140,12 @@ time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr) } if (timestr_len < 13) { - php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", timestr->data); + php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", ASN1_STRING_get0_data(timestr)); return (time_t)-1; } if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && timestr_len < 15) { - php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", timestr->data); + php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", ASN1_STRING_get0_data(timestr)); return (time_t)-1; } @@ -626,8 +626,8 @@ int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) } extension_data = X509_EXTENSION_get_data(extension); - p = extension_data->data; - length = extension_data->length; + p = ASN1_STRING_get0_data(extension_data); + length = ASN1_STRING_length(extension_data); if (method->it) { names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, &p, length, ASN1_ITEM_ptr(method->it))); diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index eea758da4713..64f49ca4538d 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -492,12 +492,12 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / } OPENSSL_free(cert_name); } else if (san->type == GEN_IPADD) { - if (san->d.iPAddress->length == 4) { + if (ASN1_STRING_length(san->d.iPAddress) == 4) { snprintf(ipbuffer, sizeof(ipbuffer), "%d.%d.%d.%d", - san->d.iPAddress->data[0], - san->d.iPAddress->data[1], - san->d.iPAddress->data[2], - san->d.iPAddress->data[3] + ASN1_STRING_get0_data(san->d.iPAddress)[0], + ASN1_STRING_get0_data(san->d.iPAddress)[1], + ASN1_STRING_get0_data(san->d.iPAddress)[2], + ASN1_STRING_get0_data(san->d.iPAddress)[3] ); if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) { sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); @@ -506,9 +506,9 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / } } #ifdef HAVE_IPV6_SAN - else if (san->d.ip->length == 16 && subject_name_is_ipv6) { + else if (ASN1_STRING_length(san->d.ip) == 16 && subject_name_is_ipv6) { ipbuffer[0] = 0; - EXPAND_IPV6_ADDRESS(ipbuffer, san->d.iPAddress->data); + EXPAND_IPV6_ADDRESS(ipbuffer, ASN1_STRING_get0_data(san->d.iPAddress)); if (strcasecmp((const char*)subject_name_ipv6_expanded, (const char*)ipbuffer) == 0) { sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); From 1f50b63369ab42bde33b2ad71be57736a689c459 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 30 Apr 2026 15:53:47 -0400 Subject: [PATCH 4/4] Fix JIT vm_interrupt (#21910) * Add observer VM interrupt JIT regression test * Fix observer VM interrupt during tracing JIT calls --- NEWS | 4 ++ ext/opcache/jit/zend_jit_ir.c | 17 ++----- ext/zend_test/observer.c | 23 +++++++++ ext/zend_test/php_test.h | 1 + .../tests/observer_jit_vm_interrupt.inc | 8 +++ .../tests/observer_jit_vm_interrupt.phpt | 50 +++++++++++++++++++ 6 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 ext/zend_test/tests/observer_jit_vm_interrupt.inc create mode 100644 ext/zend_test/tests/observer_jit_vm_interrupt.phpt diff --git a/NEWS b/NEWS index ef713ddd7255..a6fe8e2136a0 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.22 +- Opcache: + . Fixed tracing JIT crash when a VM interrupt is handled during an observed + user function call. (Levi Morrison) + - Standard: . Fixed bug GH-21689 (version_compare() incorrectly handles versions ending with a dot). (timwolla) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 4251d6b891c9..1346d141754f 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -10337,28 +10337,19 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen if (ZEND_OBSERVER_ENABLED && (!func || (func->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_GENERATOR)) == 0)) { ir_ref observer_handler; ir_ref rx = jit_FP(jit); + const zend_op *observer_opline = NULL; struct jit_observer_fcall_is_unobserved_data unobserved_data = jit_observer_fcall_is_unobserved_start(jit, func, &observer_handler, rx, func_ref); if (trace && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_INTERPRETER)) { ZEND_ASSERT(trace[1].op == ZEND_JIT_TRACE_VM || trace[1].op == ZEND_JIT_TRACE_END); - jit_SET_EX_OPLINE(jit, trace[1].opline); + observer_opline = trace[1].opline; + jit_SET_EX_OPLINE(jit, observer_opline); } else if (GCC_GLOBAL_REGS) { // EX(opline) = opline ir_STORE(jit_EX(opline), jit_IP(jit)); } jit_observer_fcall_begin(jit, rx, observer_handler); - if (trace) { - int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); - - exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } - } else { - exit_addr = NULL; - } - - zend_jit_check_timeout(jit, NULL /* we're inside the called function */, exit_addr); + zend_jit_check_timeout(jit, observer_opline, NULL); jit_observer_fcall_is_unobserved_end(jit, &unobserved_data); } diff --git a/ext/zend_test/observer.c b/ext/zend_test/observer.c index 31052ec830f7..0dfb62723bc4 100644 --- a/ext/zend_test/observer.c +++ b/ext/zend_test/observer.c @@ -78,6 +78,10 @@ static void observer_begin(zend_execute_data *execute_data) { assert_observer_opline(execute_data); + if (ZT_G(observer_set_vm_interrupt_on_begin)) { + zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + } + if (!ZT_G(observer_show_output)) { return; } @@ -146,6 +150,14 @@ static void observer_end(zend_execute_data *execute_data, zval *retval) } } +static void (*zend_test_prev_interrupt_function)(zend_execute_data *execute_data); +static void zend_test_interrupt_function(zend_execute_data *execute_data) +{ + if (zend_test_prev_interrupt_function) { + zend_test_prev_interrupt_function(execute_data); + } +} + static void observer_show_init(zend_function *fbc) { if (fbc->common.function_name) { @@ -361,6 +373,7 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("zend_test.observer.show_init_backtrace", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_init_backtrace, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.show_opcode", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_opcode, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_ENTRY("zend_test.observer.show_opcode_in_user_handler", "", PHP_INI_SYSTEM, OnUpdateString, observer_show_opcode_in_user_handler, zend_zend_test_globals, zend_test_globals) + STD_PHP_INI_BOOLEAN("zend_test.observer.set_vm_interrupt_on_begin", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_set_vm_interrupt_on_begin, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_init", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_init, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_switch", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_switch, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_destroy", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_destroy, zend_zend_test_globals, zend_test_globals) @@ -398,10 +411,20 @@ void zend_test_observer_init(INIT_FUNC_ARGS) zend_test_prev_execute_internal = zend_execute_internal; zend_execute_internal = zend_test_execute_internal; } + + if (ZT_G(observer_set_vm_interrupt_on_begin)) { + zend_test_prev_interrupt_function = zend_interrupt_function; + zend_interrupt_function = zend_test_interrupt_function; + } } void zend_test_observer_shutdown(SHUTDOWN_FUNC_ARGS) { + if (zend_interrupt_function == zend_test_interrupt_function) { + zend_interrupt_function = zend_test_prev_interrupt_function; + zend_test_prev_interrupt_function = NULL; + } + if (type != MODULE_TEMPORARY) { UNREGISTER_INI_ENTRIES(); } diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h index 7ec6f5431234..c1310db7bd70 100644 --- a/ext/zend_test/php_test.h +++ b/ext/zend_test/php_test.h @@ -45,6 +45,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test) int observer_show_init_backtrace; int observer_show_opcode; char *observer_show_opcode_in_user_handler; + int observer_set_vm_interrupt_on_begin; int observer_nesting_depth; int observer_fiber_init; int observer_fiber_switch; diff --git a/ext/zend_test/tests/observer_jit_vm_interrupt.inc b/ext/zend_test/tests/observer_jit_vm_interrupt.inc new file mode 100644 index 000000000000..426d9fdc2cb2 --- /dev/null +++ b/ext/zend_test/tests/observer_jit_vm_interrupt.inc @@ -0,0 +1,8 @@ + +--FILE-- + +--EXPECT-- +total=2438400