Skip to content

Commit 6c7e28a

Browse files
committed
Fix unstable get_iterator pointer in shm on Windows
1 parent f12cd19 commit 6c7e28a

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

Zend/zend_compile.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8575,10 +8575,13 @@ static void zend_compile_property_hooks(
85758575

85768576
ce->num_hooked_props++;
85778577

8578+
/* See zend_link_hooked_object_iter(). */
8579+
#ifndef ZEND_WIN32
85788580
if (!ce->get_iterator) {
85798581
/* Will be removed again, in case of Iterator or IteratorAggregate. */
85808582
ce->get_iterator = zend_hooked_object_get_iterator;
85818583
}
8584+
#endif
85828585

85838586
if (!prop_info->ce->parent_name) {
85848587
zend_verify_hooked_property(ce, prop_info, prop_name);
@@ -9104,6 +9107,10 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
91049107

91059108
/* We currently don't early-bind classes that implement interfaces or use traits */
91069109
if (!ce->num_interfaces && !ce->num_traits && !ce->num_hooked_prop_variance_checks
9110+
#ifdef ZEND_WIN32
9111+
/* See zend_link_hooked_object_iter(). */
9112+
&& !ce->num_hooked_props
9113+
#endif
91079114
&& !(CG(compiler_options) & ZEND_COMPILE_WITHOUT_EXECUTION)) {
91089115
if (toplevel) {
91099116
if (extends_ast) {

Zend/zend_inheritance.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,32 @@ ZEND_API inheritance_status zend_verify_property_hook_variance(const zend_proper
17461746
return zend_perform_covariant_type_check(ce, prop_info->type, ce, value_arg_info->type);
17471747
}
17481748

1749+
#ifdef ZEND_WIN32
1750+
/* Hooked properties set get_iterator, which causes issues on Windows. Windows
1751+
* attaches multiple processes to the same shm, with each process potentially
1752+
* having different addresses to the corresponding get_iterator function due to
1753+
* ASLR. This prevents us from caching the class.
1754+
*
1755+
* To at least cache the unlinked class, avoid early-binding on Windows, and set
1756+
* get_iterator during inheritance. The linked class may not use inheritance
1757+
* cache. */
1758+
static void zend_link_hooked_object_iter(zend_class_entry *ce) {
1759+
if (!ce->get_iterator && ce->num_hooked_props) {
1760+
ce->get_iterator = zend_hooked_object_get_iterator;
1761+
ce->ce_flags &= ~ZEND_ACC_CACHEABLE;
1762+
if (CG(current_linking_class) == ce) {
1763+
HashTable *ht = (HashTable*)ce->inheritance_cache;
1764+
if (ht) {
1765+
zend_hash_destroy(ht);
1766+
FREE_HASHTABLE(ht);
1767+
ce->inheritance_cache = NULL;
1768+
}
1769+
CG(current_linking_class) = NULL;
1770+
}
1771+
}
1772+
}
1773+
#endif
1774+
17491775
ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *parent_ce, bool checked) /* {{{ */
17501776
{
17511777
zend_property_info *property_info;
@@ -3550,6 +3576,10 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35503576
zend_enum_register_funcs(ce);
35513577
}
35523578

3579+
#ifdef ZEND_WIN32
3580+
zend_link_hooked_object_iter(ce);
3581+
#endif
3582+
35533583
if (parent) {
35543584
if (!(parent->ce_flags & ZEND_ACC_LINKED)) {
35553585
add_dependency_obligation(ce, parent);
@@ -3838,6 +3868,10 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
38383868
zend_begin_record_errors();
38393869
}
38403870

3871+
#ifdef ZEND_WIN32
3872+
zend_link_hooked_object_iter(ce);
3873+
#endif
3874+
38413875
zend_do_inheritance_ex(ce, parent_ce, status == INHERITANCE_SUCCESS);
38423876
if (parent_ce && parent_ce->num_interfaces) {
38433877
zend_do_inherit_interfaces(ce, parent_ce);

ext/opcache/tests/dump_property_hooks.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ opcache.enable_cli=1
66
opcache.opt_debug_level=0x20000
77
--EXTENSIONS--
88
opcache
9+
--SKIPIF--
10+
<?php
11+
if (PHP_OS_FAMILY === 'Windows') {
12+
die('skip Windows emits additional DECLARE_CLASS_DELAYED opcode');
13+
}
14+
?>
915
--FILE--
1016
<?php
1117

0 commit comments

Comments
 (0)