Skip to content

Commit aba95c2

Browse files
committed
Revert "Fix bug #68446 (bug with constant defaults and type hints)"
This reverts commit 5ef138b.
1 parent faa396c commit aba95c2

File tree

5 files changed

+47
-80
lines changed

5 files changed

+47
-80
lines changed

Zend/tests/class_constants_002.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ echo "Done\n";
2626
--EXPECTF--
2727
int(1)
2828
int(5)
29+
int(10)
2930

3031
Fatal error: Class 'NoSuchClass' not found in %s on line %d

Zend/zend_compile.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,17 +1931,17 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ
19311931
if (class_type->u.constant.type == IS_ARRAY) {
19321932
cur_arg_info->type_hint = IS_ARRAY;
19331933
if (op == ZEND_RECV_INIT) {
1934-
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || (Z_TYPE(initialization->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_AST) {
1935-
cur_arg_info->allow_null = (Z_TYPE(initialization->u.constant) != IS_NULL) + 1;
1934+
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
1935+
cur_arg_info->allow_null = 1;
19361936
} else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) {
19371937
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
19381938
}
19391939
}
19401940
} else if (class_type->u.constant.type == IS_CALLABLE) {
19411941
cur_arg_info->type_hint = IS_CALLABLE;
19421942
if (op == ZEND_RECV_INIT) {
1943-
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || (Z_TYPE(initialization->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_AST) {
1944-
cur_arg_info->allow_null = (Z_TYPE(initialization->u.constant) != IS_NULL) + 1;
1943+
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
1944+
cur_arg_info->allow_null = 1;
19451945
} else {
19461946
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL");
19471947
}

Zend/zend_execute.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -608,17 +608,7 @@ ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend
608608
return 0;
609609
}
610610

611-
static inline int zend_arg_allows_null(zend_bool allow_null, zval *default_value TSRMLS_DC)
612-
{
613-
if (allow_null < 2 || !default_value) {
614-
return allow_null;
615-
}
616-
617-
/* assuming update_constant_ex done before */
618-
return Z_TYPE_P(default_value) == IS_NULL;
619-
}
620-
621-
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, zval *defaultval, ulong fetch_type TSRMLS_DC)
611+
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC)
622612
{
623613
zend_arg_info *cur_arg_info;
624614
char *need_msg;
@@ -648,7 +638,7 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
648638
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
649639
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
650640
}
651-
} else if (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC)) {
641+
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
652642
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
653643
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
654644
}
@@ -659,7 +649,7 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
659649
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC);
660650
}
661651

662-
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC))) {
652+
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
663653
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
664654
}
665655
break;
@@ -668,7 +658,7 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
668658
if (!arg) {
669659
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "" TSRMLS_CC);
670660
}
671-
if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC))) {
661+
if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
672662
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "" TSRMLS_CC);
673663
}
674664
break;

Zend/zend_vm_def.h

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
19611961
void **p = EX(function_state).arguments - num_args;
19621962

19631963
for (i = 0; i < num_args; ++i, ++p) {
1964-
zend_verify_arg_type(fbc, i + 1, (zval *) *p, NULL, 0 TSRMLS_CC);
1964+
zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0 TSRMLS_CC);
19651965
}
19661966
}
19671967

@@ -3374,7 +3374,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
33743374

33753375
SAVE_OPLINE();
33763376
if (UNEXPECTED(param == NULL)) {
3377-
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, NULL, opline->extended_value TSRMLS_CC)) {
3377+
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
33783378
const char *space;
33793379
const char *class_name;
33803380
zend_execute_data *ptr;
@@ -3396,7 +3396,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
33963396
} else {
33973397
zval **var_ptr;
33983398

3399-
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, NULL, opline->extended_value TSRMLS_CC);
3399+
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
34003400
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
34013401
Z_DELREF_PP(var_ptr);
34023402
*var_ptr = *param;
@@ -3410,51 +3410,39 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
34103410
ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
34113411
{
34123412
USE_OPLINE
3413-
zval *assignment_value, *default_val = NULL;
3413+
zval *assignment_value;
34143414
zend_uint arg_num = opline->op1.num;
34153415
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
34163416
zval **var_ptr;
34173417

34183418
SAVE_OPLINE();
3419-
if (IS_CONSTANT_TYPE(Z_TYPE_P(opline->op2.zv))) {
3420-
ALLOC_ZVAL(default_val);
3421-
*default_val = *opline->op2.zv;
3422-
Z_SET_REFCOUNT_P(default_val, 1);
3423-
zval_update_constant(&default_val, 0 TSRMLS_CC);
3424-
}
34253419
if (param == NULL) {
3426-
if (default_val) {
3427-
assignment_value = default_val;
3420+
ALLOC_ZVAL(assignment_value);
3421+
*assignment_value = *opline->op2.zv;
3422+
if (IS_CONSTANT_TYPE(Z_TYPE_P(assignment_value))) {
3423+
Z_SET_REFCOUNT_P(assignment_value, 1);
3424+
zval_update_constant(&assignment_value, 0 TSRMLS_CC);
3425+
} else if (Z_TYPE_P(assignment_value) == IS_ARRAY) {
3426+
HashTable *ht;
3427+
3428+
ALLOC_HASHTABLE(ht);
3429+
zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(assignment_value)), NULL, ZVAL_PTR_DTOR, 0);
3430+
zend_hash_copy(ht, Z_ARRVAL_P(assignment_value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *));
3431+
Z_ARRVAL_P(assignment_value) = ht;
34283432
} else {
3429-
ALLOC_ZVAL(assignment_value);
3430-
*assignment_value = *opline->op2.zv;
3431-
if (Z_TYPE_P(assignment_value) == IS_ARRAY) {
3432-
HashTable *ht;
3433-
3434-
ALLOC_HASHTABLE(ht);
3435-
zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(assignment_value)), NULL, ZVAL_PTR_DTOR, 0);
3436-
zend_hash_copy(ht, Z_ARRVAL_P(assignment_value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *));
3437-
Z_ARRVAL_P(assignment_value) = ht;
3438-
} else {
3439-
zval_copy_ctor(assignment_value);
3440-
}
3433+
zval_copy_ctor(assignment_value);
34413434
}
34423435
INIT_PZVAL(assignment_value);
34433436
} else {
34443437
assignment_value = *param;
34453438
Z_ADDREF_P(assignment_value);
34463439
}
34473440

3448-
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, default_val, opline->extended_value TSRMLS_CC);
3441+
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
34493442
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
34503443
zval_ptr_dtor(var_ptr);
34513444
*var_ptr = assignment_value;
34523445

3453-
if (default_val && assignment_value != default_val) {
3454-
zval_dtor(default_val);
3455-
efree(default_val);
3456-
}
3457-
34583446
CHECK_EXCEPTION();
34593447
ZEND_VM_NEXT_OPCODE();
34603448
}
@@ -3481,7 +3469,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
34813469

34823470
for (; arg_num <= arg_count; ++arg_num) {
34833471
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
3484-
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, NULL, opline->extended_value TSRMLS_CC);
3472+
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
34853473
zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL);
34863474
Z_ADDREF_PP(param);
34873475
}

Zend/zend_vm_execute.h

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
541541
void **p = EX(function_state).arguments - num_args;
542542

543543
for (i = 0; i < num_args; ++i, ++p) {
544-
zend_verify_arg_type(fbc, i + 1, (zval *) *p, NULL, 0 TSRMLS_CC);
544+
zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0 TSRMLS_CC);
545545
}
546546
}
547547

@@ -861,7 +861,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
861861

862862
SAVE_OPLINE();
863863
if (UNEXPECTED(param == NULL)) {
864-
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, NULL, opline->extended_value TSRMLS_CC)) {
864+
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
865865
const char *space;
866866
const char *class_name;
867867
zend_execute_data *ptr;
@@ -883,7 +883,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
883883
} else {
884884
zval **var_ptr;
885885

886-
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, NULL, opline->extended_value TSRMLS_CC);
886+
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
887887
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
888888
Z_DELREF_PP(var_ptr);
889889
*var_ptr = *param;
@@ -916,7 +916,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
916916

917917
for (; arg_num <= arg_count; ++arg_num) {
918918
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
919-
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, NULL, opline->extended_value TSRMLS_CC);
919+
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
920920
zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL);
921921
Z_ADDREF_PP(param);
922922
}
@@ -1615,51 +1615,39 @@ static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC
16151615
static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
16161616
{
16171617
USE_OPLINE
1618-
zval *assignment_value, *default_val = NULL;
1618+
zval *assignment_value;
16191619
zend_uint arg_num = opline->op1.num;
16201620
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
16211621
zval **var_ptr;
16221622

16231623
SAVE_OPLINE();
1624-
if (IS_CONSTANT_TYPE(Z_TYPE_P(opline->op2.zv))) {
1625-
ALLOC_ZVAL(default_val);
1626-
*default_val = *opline->op2.zv;
1627-
Z_SET_REFCOUNT_P(default_val, 1);
1628-
zval_update_constant(&default_val, 0 TSRMLS_CC);
1629-
}
16301624
if (param == NULL) {
1631-
if (default_val) {
1632-
assignment_value = default_val;
1633-
} else {
1634-
ALLOC_ZVAL(assignment_value);
1635-
*assignment_value = *opline->op2.zv;
1636-
if (Z_TYPE_P(assignment_value) == IS_ARRAY) {
1637-
HashTable *ht;
1625+
ALLOC_ZVAL(assignment_value);
1626+
*assignment_value = *opline->op2.zv;
1627+
if (IS_CONSTANT_TYPE(Z_TYPE_P(assignment_value))) {
1628+
Z_SET_REFCOUNT_P(assignment_value, 1);
1629+
zval_update_constant(&assignment_value, 0 TSRMLS_CC);
1630+
} else if (Z_TYPE_P(assignment_value) == IS_ARRAY) {
1631+
HashTable *ht;
16381632

1639-
ALLOC_HASHTABLE(ht);
1640-
zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(assignment_value)), NULL, ZVAL_PTR_DTOR, 0);
1641-
zend_hash_copy(ht, Z_ARRVAL_P(assignment_value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *));
1642-
Z_ARRVAL_P(assignment_value) = ht;
1643-
} else {
1644-
zval_copy_ctor(assignment_value);
1645-
}
1633+
ALLOC_HASHTABLE(ht);
1634+
zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(assignment_value)), NULL, ZVAL_PTR_DTOR, 0);
1635+
zend_hash_copy(ht, Z_ARRVAL_P(assignment_value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *));
1636+
Z_ARRVAL_P(assignment_value) = ht;
1637+
} else {
1638+
zval_copy_ctor(assignment_value);
16461639
}
16471640
INIT_PZVAL(assignment_value);
16481641
} else {
16491642
assignment_value = *param;
16501643
Z_ADDREF_P(assignment_value);
16511644
}
16521645

1653-
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, default_val, opline->extended_value TSRMLS_CC);
1646+
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
16541647
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
16551648
zval_ptr_dtor(var_ptr);
16561649
*var_ptr = assignment_value;
16571650

1658-
if (default_val && assignment_value != default_val) {
1659-
zval_dtor(default_val);
1660-
efree(default_val);
1661-
}
1662-
16631651
CHECK_EXCEPTION();
16641652
ZEND_VM_NEXT_OPCODE();
16651653
}

0 commit comments

Comments
 (0)