Skip to content

Commit 31dd635

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fixed bug #79114 (Eval class during preload causes class to be only half available)
2 parents 99db00b + 9c2fd55 commit 31dd635

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,6 +3273,18 @@ static void preload_restart(void)
32733273
}
32743274
}
32753275

3276+
static size_t preload_try_strip_filename(zend_string *filename) {
3277+
/*FIXME: better way to hanlde eval()'d code? see COMPILED_STRING_DESCRIPTION_FORMAT */
3278+
if (ZSTR_LEN(filename) > sizeof(" eval()'d code")
3279+
&& *(ZSTR_VAL(filename) + ZSTR_LEN(filename) - sizeof(" eval()'d code")) == ':') {
3280+
const char *cfilename = ZSTR_VAL(filename);
3281+
size_t cfilenamelen = ZSTR_LEN(filename) - sizeof(" eval()'d code") - 2 /* :*/;
3282+
while (cfilenamelen && cfilename[--cfilenamelen] != '(');
3283+
return cfilenamelen;
3284+
}
3285+
return 0;
3286+
}
3287+
32763288
static void preload_move_user_functions(HashTable *src, HashTable *dst)
32773289
{
32783290
Bucket *p;
@@ -3289,7 +3301,12 @@ static void preload_move_user_functions(HashTable *src, HashTable *dst)
32893301
if (function->op_array.filename != filename) {
32903302
filename = function->op_array.filename;
32913303
if (filename) {
3292-
copy = zend_hash_exists(preload_scripts, filename);
3304+
if (!(copy = zend_hash_exists(preload_scripts, filename))) {
3305+
size_t eval_len = preload_try_strip_filename(filename);
3306+
if (eval_len) {
3307+
copy = zend_hash_str_exists(preload_scripts, ZSTR_VAL(filename), eval_len);
3308+
}
3309+
}
32933310
} else {
32943311
copy = 0;
32953312
}
@@ -3323,7 +3340,12 @@ static void preload_move_user_classes(HashTable *src, HashTable *dst)
33233340
if (ce->info.user.filename != filename) {
33243341
filename = ce->info.user.filename;
33253342
if (filename) {
3326-
copy = zend_hash_exists(preload_scripts, filename);
3343+
if (!(copy = zend_hash_exists(preload_scripts, filename))) {
3344+
size_t eval_len = preload_try_strip_filename(filename);
3345+
if (eval_len) {
3346+
copy = zend_hash_str_exists(preload_scripts, ZSTR_VAL(filename), eval_len);
3347+
}
3348+
}
33273349
} else {
33283350
copy = 0;
33293351
}

ext/opcache/tests/preload.inc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ class Z2 extends Z {}
4848
function get_anon() {
4949
return new class {};
5050
}
51+
52+
if (!isset($rt)) {
53+
eval("class Foo {}");
54+
55+
class Bar extends Foo {}
56+
57+
eval("function f3() {} ");
58+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Bug #79114 (Eval class during preload causes class to be only half available)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
opcache.preload={PWD}/preload.inc
8+
--SKIPIF--
9+
<?php
10+
require_once('skipif.inc');
11+
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
12+
?>
13+
--FILE--
14+
<?php
15+
var_dump(class_exists(Foo::class));
16+
var_dump(class_exists(Bar::class));
17+
new Bar();
18+
var_dump(class_parents('Bar'));
19+
new Foo();
20+
f3();
21+
?>
22+
--EXPECTF--
23+
bool(true)
24+
bool(true)
25+
array(1) {
26+
["Foo"]=>
27+
string(3) "Foo"
28+
}

0 commit comments

Comments
 (0)