Skip to content

Commit 38229d1

Browse files
committed
Merge remote-tracking branch 'origin/PHP-5.6'
Conflicts: Zend/zend_compile.c Zend/zend_execute.c Zend/zend_vm_def.h Zend/zend_vm_execute.h
2 parents 77f1727 + 5ef138b commit 38229d1

File tree

4 files changed

+57
-25
lines changed

4 files changed

+57
-25
lines changed

Zend/zend_compile.c

+9-5
Original file line numberDiff line numberDiff line change
@@ -3831,11 +3831,15 @@ void zend_compile_params(zend_ast *ast TSRMLS_DC) /* {{{ */
38313831
arg_info->class_name_len = 0;
38323832

38333833
if (type_ast) {
3834-
zend_bool has_null_default = default_ast
3835-
&& (Z_TYPE(default_node.u.constant) == IS_NULL
3836-
|| (Z_TYPE(default_node.u.constant) == IS_CONSTANT
3837-
&& strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0)
3838-
|| Z_TYPE(default_node.u.constant) == IS_CONSTANT_AST); // ???
3834+
zend_bool has_null_default = 0;
3835+
3836+
if (default_ast) {
3837+
if (!(has_null_default = (Z_TYPE(default_node.u.constant) == IS_NULL || (Z_TYPE(default_node.u.constant) == IS_CONSTANT && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0)))) {
3838+
if (Z_OPT_CONSTANT(default_node.u.constant)) {
3839+
has_null_default = 2;
3840+
}
3841+
}
3842+
}
38393843

38403844
op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
38413845
arg_info->allow_null = has_null_default;

Zend/zend_execute.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,17 @@ ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uin
574574
}
575575
}
576576

577-
static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg TSRMLS_DC)
577+
static inline int zend_arg_allows_null(zend_bool allow_null, zval *default_value TSRMLS_DC)
578+
{
579+
if (allow_null < 2 || !default_value) {
580+
return allow_null;
581+
}
582+
583+
/* assuming update_constant_ex done before */
584+
return Z_TYPE_P(default_value) == IS_NULL;
585+
}
586+
587+
static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *defaultval TSRMLS_DC)
578588
{
579589
zend_arg_info *cur_arg_info;
580590
char *need_msg;
@@ -601,18 +611,18 @@ static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg
601611
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
602612
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg TSRMLS_CC);
603613
}
604-
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
614+
} else if (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC)) {
605615
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
606616
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg TSRMLS_CC);
607617
}
608618
} else if (cur_arg_info->type_hint) {
609619
if (cur_arg_info->type_hint == IS_ARRAY) {
610620
ZVAL_DEREF(arg);
611-
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
621+
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))) {
612622
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg TSRMLS_CC);
613623
}
614624
} else if (cur_arg_info->type_hint == IS_CALLABLE) {
615-
if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
625+
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))) {
616626
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg TSRMLS_CC);
617627
}
618628
#if ZEND_DEBUG

Zend/zend_vm_def.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -2675,7 +2675,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
26752675
zval *p = ZEND_CALL_ARG(call, 1);
26762676

26772677
for (i = 0; i < call->num_args; ++i) {
2678-
zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
2678+
zend_verify_arg_type(fbc, i + 1, p, NULL TSRMLS_CC);
26792679
p++;
26802680
}
26812681
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -3528,7 +3528,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
35283528
} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
35293529
zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
35303530

3531-
zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
3531+
zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC);
35323532
CHECK_EXCEPTION();
35333533
}
35343534

@@ -3539,15 +3539,20 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
35393539
{
35403540
USE_OPLINE
35413541
uint32_t arg_num = opline->op1.num;
3542-
zval *param;
3542+
zval *param, default_val = {{0}};
35433543

35443544
SAVE_OPLINE();
3545+
if (Z_OPT_CONSTANT_P(opline->op2.zv)) {
3546+
ZVAL_COPY_VALUE(&default_val, opline->op2.zv);
3547+
zval_update_constant(&default_val, 0 TSRMLS_CC);
3548+
}
3549+
35453550
param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
35463551
if (arg_num > EX(num_args)) {
3547-
ZVAL_COPY_VALUE(param, opline->op2.zv);
3548-
if (Z_OPT_CONSTANT_P(param)) {
3549-
zval_update_constant(param, 0 TSRMLS_CC);
3552+
if (Z_TYPE(default_val) != IS_UNDEF) {
3553+
*param = default_val;
35503554
} else {
3555+
ZVAL_COPY_VALUE(param, opline->op2.zv);
35513556
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
35523557
if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) {
35533558
zval_copy_ctor_func(param);
@@ -3556,7 +3561,11 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
35563561
}
35573562

35583563
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
3559-
zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
3564+
zend_verify_arg_type(EX(func), arg_num, param, Z_TYPE(default_val) == IS_UNDEF ? NULL : &default_val TSRMLS_CC);
3565+
}
3566+
3567+
if (Z_TYPE(default_val) != IS_UNDEF && arg_num <= EX(num_args)) {
3568+
zval_dtor(&default_val);
35603569
}
35613570

35623571
CHECK_EXCEPTION();
@@ -3581,7 +3590,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
35813590
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
35823591
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
35833592
do {
3584-
zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
3593+
zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC);
35853594
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
35863595
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
35873596
param++;

Zend/zend_vm_execute.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
538538
zval *p = ZEND_CALL_ARG(call, 1);
539539

540540
for (i = 0; i < call->num_args; ++i) {
541-
zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
541+
zend_verify_arg_type(fbc, i + 1, p, NULL TSRMLS_CC);
542542
p++;
543543
}
544544
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -978,7 +978,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
978978
} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
979979
zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
980980

981-
zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
981+
zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC);
982982
CHECK_EXCEPTION();
983983
}
984984

@@ -1003,7 +1003,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
10031003
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
10041004
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
10051005
do {
1006-
zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
1006+
zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC);
10071007
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
10081008
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
10091009
param++;
@@ -1645,15 +1645,20 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
16451645
{
16461646
USE_OPLINE
16471647
uint32_t arg_num = opline->op1.num;
1648-
zval *param;
1648+
zval *param, default_val = {{0}};
16491649

16501650
SAVE_OPLINE();
1651+
if (Z_OPT_CONSTANT_P(opline->op2.zv)) {
1652+
ZVAL_COPY_VALUE(&default_val, opline->op2.zv);
1653+
zval_update_constant(&default_val, 0 TSRMLS_CC);
1654+
}
1655+
16511656
param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
16521657
if (arg_num > EX(num_args)) {
1653-
ZVAL_COPY_VALUE(param, opline->op2.zv);
1654-
if (Z_OPT_CONSTANT_P(param)) {
1655-
zval_update_constant(param, 0 TSRMLS_CC);
1658+
if (Z_TYPE(default_val) != IS_UNDEF) {
1659+
*param = default_val;
16561660
} else {
1661+
ZVAL_COPY_VALUE(param, opline->op2.zv);
16571662
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
16581663
if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) {
16591664
zval_copy_ctor_func(param);
@@ -1662,7 +1667,11 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
16621667
}
16631668

16641669
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
1665-
zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
1670+
zend_verify_arg_type(EX(func), arg_num, param, Z_TYPE(default_val) == IS_UNDEF ? NULL : &default_val TSRMLS_CC);
1671+
}
1672+
1673+
if (Z_TYPE(default_val) != IS_UNDEF && arg_num <= EX(num_args)) {
1674+
zval_dtor(&default_val);
16661675
}
16671676

16681677
CHECK_EXCEPTION();

0 commit comments

Comments
 (0)