1
0
mirror of https://github.com/php/php-src.git synced 2026-04-11 18:13:00 +02:00

Merge branch 'PHP-7.4'

* PHP-7.4:
  Fixed bug #78937 (Preloading unlinkable anonymous class can segfault)
This commit is contained in:
Dmitry Stogov
2019-12-11 00:47:15 +03:00
10 changed files with 162 additions and 2 deletions

View File

@@ -1104,8 +1104,12 @@ ZEND_API int do_bind_class(zval *lcname, zend_string *lc_parent_name) /* {{{ */
if (UNEXPECTED(!zv)) {
ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname));
ZEND_ASSERT(ce && "Class with lcname should be registered");
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
if (ce) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
} else {
ZEND_ASSERT(EG(current_execute_data)->func->op_array.fn_flags & ZEND_ACC_PRELOADED);
zend_error_noreturn(E_ERROR, "Class %s wasn't preloaded", Z_STRVAL_P(lcname));
}
return FAILURE;
}

View File

@@ -7108,6 +7108,11 @@ ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT)
if (UNEXPECTED(ce == NULL)) {
zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1));
zv = zend_hash_find_ex(EG(class_table), rtd_key, 1);
if (UNEXPECTED(zv == NULL)) {
SAVE_OPLINE();
ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED);
zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded");
}
ZEND_ASSERT(zv != NULL);
ce = Z_CE_P(zv);
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {

View File

@@ -2361,6 +2361,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE
if (UNEXPECTED(ce == NULL)) {
zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1));
zv = zend_hash_find_ex(EG(class_table), rtd_key, 1);
if (UNEXPECTED(zv == NULL)) {
SAVE_OPLINE();
ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED);
zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded");
}
ZEND_ASSERT(zv != NULL);
ce = Z_CE_P(zv);
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {

View File

@@ -0,0 +1,22 @@
--TEST--
Bug #78937.1 (Preloading unlinkable anonymous class can segfault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.preload={PWD}/preload_bug78937.inc
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class Bar {
}
var_dump(foo());
?>
--EXPECTF--
Warning: Can't preload unlinked class Foo: Unknown parent Bar in %spreload_bug78937.inc on line 6
Warning: Can't preload unlinked class class@anonymous: Unknown parent Bar in %spreload_bug78937.inc on line 3
Fatal error: Anonymous class wasn't preloaded in %spreload_bug78937.inc on line 3

View File

@@ -0,0 +1,22 @@
--TEST--
Bug #78937.2 (Preloading unlinkable anonymous class can segfault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.preload={PWD}/preload_bug78937.inc
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
include(__DIR__ . "/preload_bug78937.inc");
class Bar {
}
var_dump(foo());
?>
--EXPECTF--
Warning: Can't preload unlinked class Foo: Unknown parent Bar in %spreload_bug78937.inc on line 6
Warning: Can't preload unlinked class class@anonymous: Unknown parent Bar in %spreload_bug78937.inc on line 3
object(class@anonymous)#%d (0) {
}

View File

@@ -0,0 +1,24 @@
--TEST--
Bug #78937.3 (Preloading unlinkable anonymous class can segfault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.preload={PWD}/preload_bug78937.inc
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
include(__DIR__ . "/preload_bug78937.inc");
var_dump(foo());
?>
--EXPECTF--
Warning: Can't preload unlinked class Foo: Unknown parent Bar in %spreload_bug78937.inc on line 6
Warning: Can't preload unlinked class class@anonymous: Unknown parent Bar in %spreload_bug78937.inc on line 3
Fatal error: Uncaught Error: Class 'Bar' not found in %spreload_bug78937.inc:3
Stack trace:
#0 %sbug78937_3.php(3): foo()
#1 {main}
thrown in %spreload_bug78937.inc on line 3

View File

@@ -0,0 +1,22 @@
--TEST--
Bug #78937.4 (Preloading unlinkable anonymous class can segfault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.preload={PWD}/preload_bug78937.inc
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class Bar {
}
bar();
var_dump(new Foo);
?>
--EXPECTF--
Warning: Can't preload unlinked class Foo: Unknown parent Bar in %spreload_bug78937.inc on line 6
Warning: Can't preload unlinked class class@anonymous: Unknown parent Bar in %spreload_bug78937.inc on line 3
Fatal error: Class foo wasn't preloaded in %spreload_bug78937.inc on line 6

View File

@@ -0,0 +1,23 @@
--TEST--
Bug #78937.5 (Preloading unlinkable anonymous class can segfault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.preload={PWD}/preload_bug78937.inc
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
include(__DIR__ . "/preload_bug78937.inc");
class Bar {
}
bar();
var_dump(new Foo);
?>
--EXPECTF--
Warning: Can't preload unlinked class Foo: Unknown parent Bar in %spreload_bug78937.inc on line 6
Warning: Can't preload unlinked class class@anonymous: Unknown parent Bar in %spreload_bug78937.inc on line 3
object(Foo)#%d (0) {
}

View File

@@ -0,0 +1,25 @@
--TEST--
Bug #78937.6 (Preloading unlinkable anonymous class can segfault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.preload={PWD}/preload_bug78937.inc
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
include(__DIR__ . "/preload_bug78937.inc");
bar();
var_dump(new Foo);
?>
--EXPECTF--
Warning: Can't preload unlinked class Foo: Unknown parent Bar in %spreload_bug78937.inc on line 6
Warning: Can't preload unlinked class class@anonymous: Unknown parent Bar in %spreload_bug78937.inc on line 3
Fatal error: Uncaught Error: Class 'Bar' not found in %spreload_bug78937.inc:6
Stack trace:
#0 %sbug78937_6.php(3): bar()
#1 {main}
thrown in %spreload_bug78937.inc on line 6

View File

@@ -0,0 +1,8 @@
<?php
function foo() {
return new class extends Bar {};
}
function bar() {
class Foo extends Bar {
}
}