Skip to content

Commit 82ad073

Browse files
committed
Zend: add VM spec for ZEND_VERIFY_TYPE_RETURN for string values
1 parent 90473e5 commit 82ad073

File tree

3 files changed

+996
-554
lines changed

3 files changed

+996
-554
lines changed

Zend/zend_vm_def.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4570,6 +4570,64 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_VERIFY_RETURN_TYPE, (((res_info & MAY_BE_REF)
45704570
ZEND_VM_NEXT_OPCODE();
45714571
}
45724572

4573+
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_VERIFY_RETURN_TYPE, (((res_info & MAY_BE_REF) == 0) && op1_info == MAY_BE_STRING), ZEND_VERIFY_RETURN_TYPE_FOR_STRING, CONST|TMPVAR|CV, UNUSED)
4574+
{
4575+
USE_OPLINE
4576+
zval *op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4577+
uint32_t pure_type_mask = opline->extended_value;
4578+
4579+
if (UNEXPECTED(EX_USES_STRICT_TYPES() || ((pure_type_mask & (MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_BOOL)) == 0))) {
4580+
SAVE_OPLINE();
4581+
zend_verify_return_error(EX(func), op);
4582+
HANDLE_EXCEPTION();
4583+
}
4584+
4585+
zval *result = EX_VAR(opline->result.var);
4586+
4587+
if (pure_type_mask & MAY_BE_STRING) {
4588+
ZEND_VM_NEXT_OPCODE();
4589+
}
4590+
4591+
/* Type preference order: int -> float -> bool */
4592+
zend_long lval = 0;
4593+
double dval = 0;
4594+
uint8_t type = is_numeric_str_function(Z_STR_P(op), &lval, &dval);
4595+
if (type == IS_LONG) {
4596+
if (pure_type_mask & MAY_BE_LONG) {
4597+
ZVAL_LONG(result, lval);
4598+
} else if (pure_type_mask & MAY_BE_DOUBLE) {
4599+
ZVAL_DOUBLE(result, (double)lval);
4600+
} else {
4601+
ZEND_ASSERT(pure_type_mask & MAY_BE_BOOL);
4602+
ZVAL_BOOL(result, lval);
4603+
}
4604+
ZEND_VM_NEXT_OPCODE();
4605+
} else if (type == IS_DOUBLE) {
4606+
if (pure_type_mask & MAY_BE_DOUBLE) {
4607+
ZVAL_DOUBLE(result, dval);
4608+
ZEND_VM_NEXT_OPCODE();
4609+
} else if (pure_type_mask & MAY_BE_LONG) {
4610+
if (!zend_isnan(dval) && ZEND_DOUBLE_FITS_LONG(dval)) {
4611+
SAVE_OPLINE();
4612+
/* May warn */
4613+
ZVAL_LONG(result, zend_dval_to_lval_safe(dval));
4614+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4615+
}
4616+
} else {
4617+
ZVAL_BOOL(result, dval);
4618+
ZEND_VM_NEXT_OPCODE();
4619+
}
4620+
} else {
4621+
if (pure_type_mask & MAY_BE_BOOL) {
4622+
ZVAL_BOOL(result, i_zend_is_true(op));
4623+
ZEND_VM_NEXT_OPCODE();
4624+
}
4625+
}
4626+
SAVE_OPLINE();
4627+
zend_verify_return_error(EX(func), op);
4628+
HANDLE_EXCEPTION();
4629+
}
4630+
45734631
ZEND_VM_COLD_HANDLER(201, ZEND_VERIFY_NEVER_TYPE, UNUSED, UNUSED)
45744632
{
45754633
SAVE_OPLINE();

0 commit comments

Comments
 (0)