Skip to content

Commit

Permalink
Disallow non-static calls to the constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
pmmaga committed Apr 17, 2020
1 parent 7a260a4 commit eb966d2
Show file tree
Hide file tree
Showing 19 changed files with 134 additions and 138 deletions.
5 changes: 4 additions & 1 deletion Zend/tests/bug31177-2.phpt
Expand Up @@ -6,10 +6,13 @@ class foo {
function __construct($n=0) {
if($n) throw new Exception("new");
}
function another() {
return self::__construct(1);
}
}
$x = new foo();
try {
$y=$x->__construct(1);
$y=$x->another();
} catch (Exception $e) {
var_dump($x);
}
Expand Down
3 changes: 0 additions & 3 deletions Zend/tests/bug35634.phpt
Expand Up @@ -14,9 +14,6 @@ if (defined("pass3")) {
class TestClass {
function __construct() {
}
function TestClass() {
$this->__construct();
}
}

} else {
Expand Down
6 changes: 5 additions & 1 deletion Zend/tests/bug60536_001.phpt
Expand Up @@ -16,9 +16,13 @@ class Z extends Y {
function __construct() {
return ++$this->x;
}

function another() {
self::__construct();
}
}
$a = new Z();
$a->__construct();
$a->another();
echo "DONE";
?>
--EXPECTF--
Expand Down
9 changes: 9 additions & 0 deletions Zend/tests/constructor_instance_001.phpt
@@ -0,0 +1,9 @@
--TEST--
Not allowed to call the constructor on an object instance
--FILE--
<?php
class C {}
$c = new C();
$c->__construct();
--EXPECTF--
Fatal error: Cannot call the constructor on an object instance %s
15 changes: 15 additions & 0 deletions Zend/tests/constructor_instance_002.phpt
@@ -0,0 +1,15 @@
--TEST--
Not allowed to call the constructor on an object instance
--FILE--
<?php
class C {
function __construct() {}
}
$c = new C();
$constr = '__construct';
$c->$constr();
--EXPECTF--
Fatal error: Uncaught Error: Cannot call the constructor on an object instance %s
Stack trace:
#0 {main}
thrown %s
16 changes: 10 additions & 6 deletions Zend/zend_compile.c
Expand Up @@ -4101,6 +4101,12 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
}
/* }}} */

static zend_bool zend_is_constructor(zend_string *name) /* {{{ */
{
return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME);
}
/* }}} */

void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
{
zend_ast *obj_ast = ast->child[0];
Expand Down Expand Up @@ -4130,6 +4136,10 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
}

if (zend_is_constructor(Z_STR_P(&method_node.u.constant))) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot call the constructor on an object instance");
}

opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_func_name_literal(
Z_STR(method_node.u.constant));
Expand All @@ -4155,12 +4165,6 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
}
/* }}} */

static zend_bool zend_is_constructor(zend_string *name) /* {{{ */
{
return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME);
}
/* }}} */

static zend_function *zend_get_compatible_func_or_null(zend_class_entry *ce, zend_string *lcname) /* {{{ */
{
zend_function *fbc = zend_hash_find_ptr(&ce->function_table, lcname);
Expand Down
7 changes: 7 additions & 0 deletions Zend/zend_vm_def.h
Expand Up @@ -3470,6 +3470,13 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");
FREE_OP2();
FREE_OP1();
HANDLE_EXCEPTION();
}

if (OP2_TYPE != IS_CONST) {
FREE_OP2();
}
Expand Down
84 changes: 84 additions & 0 deletions Zend/zend_vm_execute.h
Expand Up @@ -5678,6 +5678,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");


HANDLE_EXCEPTION();
}

if (IS_CONST != IS_CONST) {

}
Expand Down Expand Up @@ -7853,6 +7860,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));

HANDLE_EXCEPTION();
}

if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
}
Expand Down Expand Up @@ -10109,6 +10123,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");


HANDLE_EXCEPTION();
}

if (IS_CV != IS_CONST) {

}
Expand Down Expand Up @@ -14400,6 +14421,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");

zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}

if (IS_CONST != IS_CONST) {

}
Expand Down Expand Up @@ -15781,6 +15809,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}

if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
}
Expand Down Expand Up @@ -17056,6 +17091,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");

zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}

if (IS_CV != IS_CONST) {

}
Expand Down Expand Up @@ -30533,6 +30575,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");


HANDLE_EXCEPTION();
}

if (IS_CONST != IS_CONST) {

}
Expand Down Expand Up @@ -32401,6 +32450,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));

HANDLE_EXCEPTION();
}

if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
}
Expand Down Expand Up @@ -34795,6 +34851,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");


HANDLE_EXCEPTION();
}

if (IS_CV != IS_CONST) {

}
Expand Down Expand Up @@ -39644,6 +39707,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");


HANDLE_EXCEPTION();
}

if (IS_CONST != IS_CONST) {

}
Expand Down Expand Up @@ -43081,6 +43151,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));

HANDLE_EXCEPTION();
}

if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
}
Expand Down Expand Up @@ -47963,6 +48040,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
}
}

if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CTOR) != 0)) {
zend_throw_error(NULL, "Cannot call the constructor on an object instance");


HANDLE_EXCEPTION();
}

if (IS_CV != IS_CONST) {

}
Expand Down
19 changes: 0 additions & 19 deletions ext/dom/tests/DOMComment_construct_basic_001.phpt

This file was deleted.

16 changes: 0 additions & 16 deletions ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt

This file was deleted.

20 changes: 0 additions & 20 deletions ext/dom/tests/bug66502.phpt

This file was deleted.

15 changes: 0 additions & 15 deletions ext/fileinfo/tests/finfo_open_002.phpt

This file was deleted.

19 changes: 0 additions & 19 deletions ext/intl/tests/bug62081.phpt

This file was deleted.

2 changes: 0 additions & 2 deletions ext/phar/tests/phar_oo_001.phpt
Expand Up @@ -34,7 +34,6 @@ catch (LogicException $e)
}
try {
$phar = new Phar('test.phar');
$phar->__construct('oops');
} catch (LogicException $e)
{
var_dump($e->getMessage());
Expand All @@ -50,4 +49,3 @@ __halt_compiler();
string(5) "1.0.0"
int(5)
string(50) "Cannot call method on an uninitialized Phar object"
string(29) "Cannot call constructor twice"

0 comments on commit eb966d2

Please sign in to comment.