mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-13433: Segmentation Fault in zend_class_init_statics when using opcache.preload
This regressed in9a250cc9d6, which allowed static properties to get overridden by a trait during inheritance. In particular, because of the change to the loop in zend_update_parent_ce(), it's not guaranteed that all indirects are after one another. This means that during persisting the zvals of the static members table, some static properties may be skipped. In case of the test code, this means that the array in the trait will keep referring to the old, new freed, stale value. To solve this, we check the type for IS_INDIRECT, which is the same as what zend_persist_calc() is already doing anyway. Since2543e61aedwe can check for IS_INDIRECT to see if it should be persisted or not. Closes GH-13794.
This commit is contained in:
3
NEWS
3
NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.3.6
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug GH-13433 (Segmentation Fault in zend_class_init_statics when
|
||||
using opcache.preload). (nielsdos)
|
||||
|
||||
28 Mar 2024, PHP 8.3.5RC1
|
||||
|
||||
|
||||
4
ext/opcache/tests/gh13433/ParentClass.inc
Normal file
4
ext/opcache/tests/gh13433/ParentClass.inc
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
abstract class ParentClass {
|
||||
use TraitA;
|
||||
}
|
||||
8
ext/opcache/tests/gh13433/TheClass.inc
Normal file
8
ext/opcache/tests/gh13433/TheClass.inc
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
class TheClass extends ParentClass {
|
||||
use TraitA;
|
||||
|
||||
public function test() {
|
||||
return self::$non_empty_array;
|
||||
}
|
||||
}
|
||||
4
ext/opcache/tests/gh13433/TraitA.inc
Normal file
4
ext/opcache/tests/gh13433/TraitA.inc
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
trait TraitA {
|
||||
protected static $non_empty_array = ['non-empty'];
|
||||
}
|
||||
28
ext/opcache/tests/gh13433/gh13433.phpt
Normal file
28
ext/opcache/tests/gh13433/gh13433.phpt
Normal file
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
GH-13433 (Segmentation Fault in zend_class_init_statics when using opcache.preload)
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.optimization_level=0
|
||||
opcache.preload={PWD}/preload.inc
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$instance = new TheClass;
|
||||
var_dump($instance);
|
||||
var_dump($instance->test());
|
||||
?>
|
||||
OK
|
||||
--EXPECT--
|
||||
object(TheClass)#1 (0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(9) "non-empty"
|
||||
}
|
||||
OK
|
||||
4
ext/opcache/tests/gh13433/preload.inc
Normal file
4
ext/opcache/tests/gh13433/preload.inc
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
require __DIR__.'/TraitA.inc';
|
||||
require __DIR__.'/ParentClass.inc';
|
||||
require __DIR__.'/TheClass.inc';
|
||||
@@ -903,10 +903,11 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce)
|
||||
ce->default_static_members_table = zend_shared_memdup_free(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count);
|
||||
|
||||
/* Persist only static properties in this class.
|
||||
* Static properties from parent classes will be handled in class_copy_ctor */
|
||||
i = (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) ? ce->parent->default_static_members_count : 0;
|
||||
for (; i < ce->default_static_members_count; i++) {
|
||||
zend_persist_zval(&ce->default_static_members_table[i]);
|
||||
* Static properties from parent classes will be handled in class_copy_ctor and are marked with IS_INDIRECT */
|
||||
for (i = 0; i < ce->default_static_members_count; i++) {
|
||||
if (Z_TYPE(ce->default_static_members_table[i]) != IS_INDIRECT) {
|
||||
zend_persist_zval(&ce->default_static_members_table[i]);
|
||||
}
|
||||
}
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
if (ce->ce_flags & ZEND_ACC_LINKED) {
|
||||
|
||||
Reference in New Issue
Block a user