Skip to content

Commit 1c17dbc

Browse files
committed
add more tests and fix a small visibility issue
1 parent 68f5063 commit 1c17dbc

File tree

3 files changed

+66
-4
lines changed

3 files changed

+66
-4
lines changed

Zend/zend_API.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,17 +1816,19 @@ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zen
18161816
return FAILURE;
18171817
}
18181818

1819-
if (class_type->required_scope) {
1820-
const zend_class_entry *scope = zend_get_executed_scope();
1819+
const zend_class_entry *check_class = class_type;
1820+
const zend_class_entry *scope = zend_get_executed_scope();
1821+
check_lexical_scope:
1822+
if (check_class->required_scope) {
18211823
if (UNEXPECTED(scope == NULL)) {
18221824
zend_type_error("Cannot instantiate class %s from the global scope", ZSTR_VAL(class_type->name));
18231825
ZVAL_NULL(arg);
18241826
Z_OBJ_P(arg) = NULL;
18251827
return FAILURE;
18261828
}
18271829

1828-
if (class_type->required_scope_absolute) {
1829-
if (scope != class_type->required_scope && scope->lexical_scope != class_type->required_scope) {
1830+
if (check_class->required_scope_absolute) {
1831+
if (scope != check_class->required_scope && scope->lexical_scope != check_class->required_scope) {
18301832
zend_type_error("Cannot instantiate private class %s from scope %s", ZSTR_VAL(class_type->name), ZSTR_VAL(scope->name));
18311833
ZVAL_NULL(arg);
18321834
Z_OBJ_P(arg) = NULL;
@@ -1837,6 +1839,11 @@ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zen
18371839
}
18381840
}
18391841

1842+
if (check_class != scope && check_class->lexical_scope && check_class->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
1843+
check_class = check_class->lexical_scope;
1844+
goto check_lexical_scope;
1845+
}
1846+
18401847
if (UNEXPECTED(!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
18411848
if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) {
18421849
ZVAL_NULL(arg);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
returning private class via interface
3+
--FILE--
4+
<?php
5+
interface test {
6+
static function foo(): self;
7+
}
8+
9+
class Outer {
10+
private class Middle {
11+
public class Inner implements test {
12+
public static function foo(): self {
13+
return new self();
14+
}
15+
}
16+
}
17+
private function foo(Middle\Inner $inner) {} // we can see Middle\Inner here
18+
public function test(): test {
19+
$this->foo($return = Middle\Inner::foo());
20+
return $return;
21+
}
22+
}
23+
24+
var_dump(new Outer()->test());
25+
var_dump(new Outer\Middle\Inner());
26+
?>
27+
--EXPECTF--
28+
object(Outer\Middle\Inner)#2 (0) {
29+
}
30+
31+
Fatal error: Uncaught TypeError: Cannot instantiate class Outer\Middle\Inner from the global scope in %s:%d
32+
Stack trace:
33+
#0 {main}
34+
thrown in %s on line %d
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
instantiate nested private classes
3+
--FILE--
4+
<?php
5+
class Outer {
6+
private class Middle {
7+
public class Inner {}
8+
}
9+
10+
private Middle\Inner $inner;
11+
12+
public function __construct() {
13+
$this->inner = new Middle\Inner();
14+
}
15+
}
16+
17+
$x = new Outer();
18+
echo "success\n";
19+
?>
20+
--EXPECT--
21+
success

0 commit comments

Comments
 (0)