Skip to content

Commit b726cd6

Browse files
committed
Prevent reducing visibility to private(namespace) in child classes
Ensure child classes cannot reduce the visibility of inherited public or protected methods/properties to private(namespace). This would violate the Liskov Substitution Principle. Like private members, private(namespace) members are not inherited: * Methods: Skip inheritance checks when parent method is private(namespace) * Properties: Skip inheritance checks when parent property is private(namespace) The existing visibility comparison logic (using ZEND_ACC_PPP_MASK bit values) correctly prevents reducing public/protected to private(namespace). Note: Defining a NEW private(namespace) method/property with the same name as a parent's private(namespace) member is allowed, since namespace-private members are not inherited.
1 parent fa8ceaf commit b726cd6

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

Zend/zend_inheritance.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,12 +1150,15 @@ static inheritance_status do_inheritance_check_on_method(
11501150
} \
11511151
} while(0)
11521152

1153-
if (UNEXPECTED((parent_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR)) == ZEND_ACC_PRIVATE)) {
1153+
if (UNEXPECTED(
1154+
((parent_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR)) == ZEND_ACC_PRIVATE)
1155+
|| ((parent_flags & (ZEND_ACC_NAMESPACE_PRIVATE|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR)) == ZEND_ACC_NAMESPACE_PRIVATE)
1156+
)) {
11541157
if (flags & ZEND_INHERITANCE_SET_CHILD_CHANGED) {
11551158
SEPARATE_METHOD();
11561159
child->common.fn_flags |= ZEND_ACC_CHANGED;
11571160
}
1158-
/* The parent method is private and not an abstract so we don't need to check any inheritance rules */
1161+
/* The parent method is private/private(namespace) and not abstract so we don't need to check any inheritance rules */
11591162
return INHERITANCE_SUCCESS;
11601163
}
11611164

@@ -1455,14 +1458,14 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
14551458

14561459
if (UNEXPECTED(child)) {
14571460
zend_property_info *child_info = Z_PTR_P(child);
1458-
if (parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_CHANGED)) {
1461+
if (parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_NAMESPACE_PRIVATE|ZEND_ACC_CHANGED)) {
14591462
child_info->flags |= ZEND_ACC_CHANGED;
14601463
}
14611464
if (parent_info->flags & ZEND_ACC_FINAL) {
14621465
zend_error_noreturn(E_COMPILE_ERROR, "Cannot override final property %s::$%s",
14631466
ZSTR_VAL(parent_info->ce->name), ZSTR_VAL(key));
14641467
}
1465-
if (!(parent_info->flags & ZEND_ACC_PRIVATE)) {
1468+
if (!(parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_NAMESPACE_PRIVATE))) {
14661469
if (!(parent_info->ce->ce_flags & ZEND_ACC_INTERFACE)) {
14671470
child_info->prototype = parent_info->prototype;
14681471
}

0 commit comments

Comments
 (0)