com php-src: Fixed bug #61970: Allow a child class to restrict access to ctor: NEWS Zend/tests/bug61970.phpt Zend/tests/bug6197 0_1.phpt Zend/tests/bug61970_2.phpt Zend/zend_inheritance.c ext/mysqli/tests/bug380 03.phpt
[email protected] (Nikita Popov)
| Newsgroups | php.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit: 5324fb1f348f5bc979d9b5f13ac74177b73f9bf7 Author: Pedro Magalhães <[email protected]> Fri, 10 Mar 2017 20:08:15 +0100 Committer: Nikita Popov <[email protected]> Mon, 1 May 2017 14:15:57 +0200 Parents: 92124f9cdc20c6a9c22f9b54092ef945c41f2bb5 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=5324fb1f348f5bc979d9b5f13ac74177b73f9bf7 Log: Fixed bug #61970: Allow a child class to restrict access to ctor Bugs: https://bugs.php.net/61970 Changed paths: M NEWS A Zend/tests/bug61970.phpt A Zend/tests/bug61970_1.phpt A Zend/tests/bug61970_2.phpt M Zend/zend_inheritance.c M ext/mysqli/tests/bug38003.phpt Diff: diff --git a/NEWS b/NEWS index 80aa4ec..2e20313 100644 --- a/NEWS +++ b/NEWS @@ -43,6 +43,8 @@ PHP NEWS (Sammy Kaye Powers) . Fixed bug #74269 (It's possible to override trait property with different loosely-equal value). (pmmaga) + . Fixed bug #61970 (Restraining __construct() access level in subclass gives + a fatal error). (pmmaga) - BCMath: . Fixed bug #46564 (bcmod truncates fractionals). (liborm85) diff --git a/Zend/tests/bug61970.phpt b/Zend/tests/bug61970.phpt new file mode 100644 index 0000000..9cdb87a --- /dev/null +++ b/Zend/tests/bug61970.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #61970 (Restraining __construct() access level in subclass gives a fatal error) +--FILE-- +<?php + +class Foo { + public function __construct(){} +} + +class Bar extends Foo { + protected function __construct(){} +} + +echo 'DONE'; +--EXPECT-- +DONE diff --git a/Zend/tests/bug61970_1.phpt b/Zend/tests/bug61970_1.phpt new file mode 100644 index 0000000..978884a --- /dev/null +++ b/Zend/tests/bug61970_1.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #61970 (Restraining __construct() access level in subclass gives a fatal error - stays when implementing abstract) +--FILE-- +<?php + +abstract class Foo { + abstract public function __construct(); +} + +class Bar extends Foo { + protected function __construct(){} +} + +--EXPECTF-- +Fatal error: Access level to Bar::__construct() must be public (as in class Foo) in %s diff --git a/Zend/tests/bug61970_2.phpt b/Zend/tests/bug61970_2.phpt new file mode 100644 index 0000000..56203f7 --- /dev/null +++ b/Zend/tests/bug61970_2.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #61970 (Restraining __construct() access level in subclass gives a fatal error - stays when inheriting implemented abstract) +--FILE-- +<?php + +abstract class Foo { + abstract public function __construct(); +} + +class Bar extends Foo { + public function __construct(){} +} + +class Baz extends Bar { + protected function __construct(){} +} + +--EXPECTF-- +Fatal error: Access level to Baz::__construct() must be public (as in class Bar) in %s diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 675d8c4..85c5c57 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -578,8 +578,9 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); } - /* Prevent derived classes from restricting access that was available in parent classes */ - if (UNEXPECTED((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK))) { + /* Prevent derived classes from restricting access that was available in parent classes (except deriving from non-abstract ctors) */ + if (UNEXPECTED((!(child_flags & ZEND_ACC_CTOR) || (parent_flags & (ZEND_ACC_ABSTRACT | ZEND_ACC_IMPLEMENTED_ABSTRACT))) && + (child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK))) { zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } diff --git a/ext/mysqli/tests/bug38003.phpt b/ext/mysqli/tests/bug38003.phpt index f3a4823..a974815 100644 --- a/ext/mysqli/tests/bug38003.phpt +++ b/ext/mysqli/tests/bug38003.phpt @@ -17,5 +17,7 @@ $DB = new DB(); echo "Done\n"; ?> --EXPECTF-- -Fatal error: Access level to DB::__construct() must be public (as in class mysqli) in %s%ebug38003.php on line %d - +Fatal error: Uncaught Error: Call to private DB::__construct() from invalid context in %s +Stack trace: +#0 {main} + thrown in %s