Skip to content

Commit e20914f

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

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,6 +3418,23 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
34183418
} while (0)
34193419
#endif
34203420

3421+
#ifdef ZEND_WIN32
3422+
/* Hooked properties set get_iterator, which causes issues on Windows. Windows
3423+
* attaches multiple processes to the same shm, with each process potentially
3424+
* having different addresses to the corresponding get_iterator function due to
3425+
* ASLR. This prevents us from caching the class.
3426+
*
3427+
* To at least cache the unlinked class, avoid early-binding on Windows, and set
3428+
* get_iterator during inheritance. The linked class may not use inheritance
3429+
* cache. */
3430+
static void zend_link_hooked_object_iter(zend_class_entry *ce, uint32_t *is_cacheable) {
3431+
if (!ce->get_iterator && ce->num_hooked_props) {
3432+
ce->get_iterator = zend_hooked_object_get_iterator;
3433+
*is_cacheable = 0;
3434+
}
3435+
}
3436+
#endif
3437+
34213438
ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_name, zend_string *key) /* {{{ */
34223439
{
34233440
/* Load parent/interface dependencies first, so we can still gracefully abort linking
@@ -3500,6 +3517,10 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35003517
}
35013518
#endif
35023519

3520+
#ifdef ZEND_WIN32
3521+
zend_link_hooked_object_iter(ce, &is_cacheable);
3522+
#endif
3523+
35033524
bool orig_record_errors = EG(record_errors);
35043525

35053526
if (ce->ce_flags & ZEND_ACC_IMMUTABLE && is_cacheable) {

0 commit comments

Comments
 (0)