Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 31 additions & 29 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,44 +624,46 @@ ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_l
return zend_parse_arg_long_weak(arg, dest, arg_num);
}

ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */
ZEND_API double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
*dest = (double)Z_LVAL_P(arg);
return Z_LVAL_P(arg);
} else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
zend_long l;
double dval;
uint8_t type;

if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) {
if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, &dval)) != IS_DOUBLE)) {
if (EXPECTED(type != 0)) {
*dest = (double)(l);
return (double)(l);
} else {
return 0;
return NAN;
}
} else {
return dval;
}
} else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("float", arg_num)) {
return 0;
return NAN;
}
*dest = 0.0;
return 0.0;
} else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
*dest = 1.0;
return 1.0;
} else {
return 0;
return NAN;
}
return 1;
}
/* }}} */

ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */
ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
/* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */
*dest = (double)Z_LVAL_P(arg);
return (double)Z_LVAL_P(arg);
} else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
return NAN;
}
return zend_parse_arg_double_weak(arg, dest, arg_num);
return zend_parse_arg_double_weak(arg, arg_num);
}
/* }}} */

Expand Down Expand Up @@ -728,58 +730,58 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **
return true;
}

ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string", arg_num)) {
return 0;
return NULL;
}
convert_to_string(arg);
*dest = Z_STR_P(arg);
return Z_STR_P(arg);
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
zend_object *zobj = Z_OBJ_P(arg);
zval obj;
if (zobj->handlers->cast_object(zobj, &obj, IS_STRING) == SUCCESS) {
OBJ_RELEASE(zobj);
ZVAL_COPY_VALUE(arg, &obj);
*dest = Z_STR_P(arg);
return 1;
return Z_STR_P(arg);
}
return 0;
return NULL;
} else {
return 0;
return NULL;
}
return 1;
}
/* }}} */

ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
return NULL;
}
return zend_parse_arg_str_weak(arg, dest, arg_num);
return zend_parse_arg_str_weak(arg, arg_num);
}
/* }}} */

ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num)
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num)
{
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
return 0;
return NULL;
}
return zend_parse_arg_str_weak(arg, dest, arg_num);
return zend_parse_arg_str_weak(arg, arg_num);
}

ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num) /* {{{ */
{
zend_string *str;
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) {
*dest_str = NULL;
return 1;
} else if (zend_parse_arg_str_weak(arg, dest_str, arg_num)) {
} else if ((str = zend_parse_arg_str_weak(arg, arg_num)) != NULL) {
*dest_long = 0;
*dest_str = str;
return 1;
} else {
return 0;
Expand Down
26 changes: 17 additions & 9 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -2178,16 +2178,16 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num);
ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num);
ZEND_API double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num);
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num);
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num);

ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);

static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless)
Expand Down Expand Up @@ -2253,7 +2253,8 @@ static zend_always_inline bool zend_parse_arg_double(const zval *arg, double *de
*is_null = 1;
*dest = 0.0;
} else {
return zend_parse_arg_double_slow(arg, dest, arg_num);
*dest = zend_parse_arg_double_slow(arg, arg_num);
return !zend_isnan(*dest);
}
return 1;
}
Expand Down Expand Up @@ -2289,10 +2290,16 @@ static zend_always_inline bool zend_parse_arg_str_ex(zval *arg, zend_string **de
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*dest = NULL;
} else {
zend_string *str;
if (frameless) {
return zend_flf_parse_arg_str_slow(arg, dest, arg_num);
str = zend_flf_parse_arg_str_slow(arg, arg_num);
} else {
return zend_parse_arg_str_slow(arg, dest, arg_num);
str = zend_parse_arg_str_slow(arg, arg_num);
}
if (str) {
*dest = str;
} else {
return 0;
}
}
return 1;
Expand Down Expand Up @@ -2526,7 +2533,8 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_str(
*dest_str = NULL;
} else {
*dest_ht = NULL;
return zend_parse_arg_str_slow(arg, dest_str, arg_num);
*dest_str = zend_parse_arg_str_slow(arg, arg_num);
return *dest_str != NULL;
}
return 1;
}
Expand Down
17 changes: 9 additions & 8 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
{
zend_long lval;
double dval;
zend_string *str;
bool bval;

/* Type preference order: int -> float -> string -> bool */
Expand All @@ -760,12 +759,15 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
return false;
}
}
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) {
zval_ptr_dtor(arg);
ZVAL_DOUBLE(arg, dval);
return true;
if (type_mask & MAY_BE_DOUBLE) {
dval = zend_parse_arg_double_weak(arg, 0);
if (EXPECTED(!zend_isnan(dval))) {
zval_ptr_dtor(arg);
ZVAL_DOUBLE(arg, dval);
return true;
}
}
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str, 0)) {
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, 0)) {
/* on success "arg" is converted to IS_STRING */
return true;
}
Expand Down Expand Up @@ -793,15 +795,14 @@ static bool can_convert_to_string(const zval *zv) {
static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, const zval *arg)
{
zend_long lval;
double dval;
bool bval;

/* Pass (uint32_t)-1 as arg_num to indicate to ZPP not to emit any deprecation notice,
* this is needed because the version with side effects also uses 0 (e.g. for typed properties) */
if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, &lval, (uint32_t)-1)) {
return true;
}
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, (uint32_t)-1)) {
if ((type_mask & MAY_BE_DOUBLE) && !zend_isnan(zend_parse_arg_double_weak(arg, (uint32_t)-1))) {
return true;
}
if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) {
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_frameless_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
dest_ht = NULL; \
ZVAL_COPY(&str_tmp, arg ## arg_num); \
arg ## arg_num = &str_tmp; \
if (!zend_flf_parse_arg_str_slow(arg ## arg_num, &dest_str, arg_num)) { \
if (!(dest_str = zend_flf_parse_arg_str_slow(arg ## arg_num, arg_num))) { \
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_STRING, arg ## arg_num); \
goto flf_clean; \
} \
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -8823,8 +8823,8 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMP|CV, ANY)
strict = EX_USES_STRICT_TYPES();
do {
if (EXPECTED(!strict)) {
zend_string *str;
zval tmp;
zend_string *str;

if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
zend_error(E_DEPRECATED,
Expand All @@ -8837,7 +8837,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMP|CV, ANY)
}

ZVAL_COPY(&tmp, value);
if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
zval_ptr_dtor(&tmp);
break;
Expand Down
24 changes: 12 additions & 12 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading