Cleanup.
/* }}} */
ZEND_API void zend_wrong_param_count(void) /* {{{ */
-{
- if (ZEND_ARG_USES_STRICT_TYPES()) {
- zend_wrong_param_count_ex(1);
- } else {
- zend_wrong_param_count_ex(0);
- }
-}
-/* }}} */
-
-ZEND_API void zend_wrong_param_count_ex(zend_bool strict) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
- zend_internal_type_error(strict, "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
}
/* }}} */
}
/* }}} */
-ZEND_API int parse_arg_object_to_str(zval *arg, zend_string **str, int type) /* {{{ */
-{
- if (Z_OBJ_HANDLER_P(arg, cast_object)) {
- zval obj;
- if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, type) == SUCCESS) {
- zval_ptr_dtor(arg);
- ZVAL_COPY_VALUE(arg, &obj);
- *str = Z_STR_P(arg);
- return SUCCESS;
- }
- }
- /* Standard PHP objects */
- if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) {
- SEPARATE_ZVAL_NOREF(arg);
- if (zend_std_cast_object_tostring(arg, arg, type) == SUCCESS) {
- *str = Z_STR_P(arg);
- return SUCCESS;
- }
- }
- if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) {
- zval rv;
- zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv);
- Z_ADDREF_P(z);
- if(Z_TYPE_P(z) != IS_OBJECT) {
- zval_dtor(arg);
- ZVAL_NULL(arg);
- if (!zend_make_printable_zval(z, arg)) {
- ZVAL_ZVAL(arg, z, 1, 1);
- }
- *str = Z_STR_P(arg);
- return SUCCESS;
- }
- zval_ptr_dtor(z);
- }
- return FAILURE;
-}
-/* }}} */
-
#ifdef FAST_ZPP
-ZEND_API void zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args, zend_bool strict) /* {{{ */
+ZEND_API void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args) /* {{{ */
{
zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
- zend_internal_type_error(strict, "%s%s%s() expects %s %d parameter%s, %d given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given",
class_name, \
class_name[0] ? "::" : "", \
active_function->common.function_name->val,
}
/* }}} */
-ZEND_API void zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg, zend_bool strict) /* {{{ */
+ZEND_API void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
NULL
};
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be %s, %s given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
}
/* }}} */
-ZEND_API void zend_wrong_paramer_class_error(int num, char *name, zval *arg, zend_bool strict) /* {{{ */
+ZEND_API void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be %s, %s given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
}
/* }}} */
-ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend_bool strict) /* {{{ */
+ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
if (severity == E_WARNING) {
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be a valid callback, %s",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s",
class_name, space, get_active_function_name(), num, error);
} else {
zend_error(severity, "%s%s%s() expects parameter %d to be a valid callback, %s",
}
/* }}} */
-ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null, zend_bool strict) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */
{
zend_class_entry *ce_base = *pce;
const char *space;
const char *class_name = get_active_class_name(&space);
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
class_name, space, get_active_function_name(), num,
ce_base->name->val, Z_STRVAL_P(arg));
*pce = NULL;
const char *space;
const char *class_name = get_active_class_name(&space);
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be a valid class name, '%s' given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid class name, '%s' given",
class_name, space, get_active_function_name(), num,
Z_STRVAL_P(arg));
return 0;
/* }}} */
#endif
-static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity, zend_bool strict) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest) /* {{{ */
+{
+ if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
+ *dest = zend_is_true(arg);
+ } else {
+ return 0;
+ }
+ return 1;
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest) /* {{{ */
+{
+ if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
+ return 0;
+ }
+ return zend_parse_arg_bool_weak(arg, dest);
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest) /* {{{ */
+{
+ if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
+ if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
+ return 0;
+ }
+ if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
+ return 0;
+ } else {
+ *dest = zend_dval_to_lval(Z_DVAL_P(arg));
+ }
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
+ double d;
+ int type;
+
+ if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
+ if (EXPECTED(type != 0)) {
+ if (UNEXPECTED(zend_isnan(d))) {
+ return 0;
+ }
+ if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
+ return 0;
+ } else {
+ *dest = zend_dval_to_lval(d);
+ }
+ } else {
+ return 0;
+ }
+ }
+ } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
+ *dest = 0;
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
+ *dest = 1;
+ } else {
+ return 0;
+ }
+ return 1;
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest) /* {{{ */
+{
+ if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
+ return 0;
+ }
+ return zend_parse_arg_long_weak(arg, dest);
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest) /* {{{ */
+{
+ if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
+ if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
+ return 0;
+ }
+ if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
+ *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
+ } else {
+ *dest = zend_dval_to_lval(Z_DVAL_P(arg));
+ }
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
+ double d;
+ int type;
+
+ if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
+ if (EXPECTED(type != 0)) {
+ if (UNEXPECTED(zend_isnan(d))) {
+ return 0;
+ }
+ if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
+ *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
+ } else {
+ *dest = zend_dval_to_lval(d);
+ }
+ } else {
+ return 0;
+ }
+ }
+ } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
+ *dest = 0;
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
+ *dest = 1;
+ } else {
+ return 0;
+ }
+ return 1;
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest) /* {{{ */
+{
+ if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
+ return 0;
+ }
+ return zend_parse_arg_long_cap_weak(arg, dest);
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest) /* {{{ */
+{
+ if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
+ *dest = (double)Z_LVAL_P(arg);
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
+ zend_long l;
+ int type;
+
+ if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) {
+ if (EXPECTED(type != 0)) {
+ *dest = (double)(l);
+ } else {
+ return 0;
+ }
+ }
+ } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
+ *dest = 0.0;
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
+ *dest = 1.0;
+ } else {
+ return 0;
+ }
+ return 1;
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest) /* {{{ */
+{
+ 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);
+ } else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
+ return 0;
+ }
+ return zend_parse_arg_double_weak(arg, dest);
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest) /* {{{ */
+{
+ if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
+ convert_to_string(arg);
+ *dest = Z_STR_P(arg);
+ } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
+ if (Z_OBJ_HANDLER_P(arg, cast_object)) {
+ zval obj;
+ if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, IS_STRING) == SUCCESS) {
+ zval_ptr_dtor(arg);
+ ZVAL_COPY_VALUE(arg, &obj);
+ *dest = Z_STR_P(arg);
+ return 1;
+ }
+ }
+ /* Standard PHP objects */
+ if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) {
+ SEPARATE_ZVAL_NOREF(arg);
+ if (zend_std_cast_object_tostring(arg, arg, IS_STRING) == SUCCESS) {
+ *dest = Z_STR_P(arg);
+ return 1;
+ }
+ }
+ if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) {
+ zval rv;
+ zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv);
+
+ Z_ADDREF_P(z);
+ if (Z_TYPE_P(z) != IS_OBJECT) {
+ zval_dtor(arg);
+ ZVAL_NULL(arg);
+ if (!zend_make_printable_zval(z, arg)) {
+ ZVAL_ZVAL(arg, z, 1, 1);
+ }
+ *dest = Z_STR_P(arg);
+ return 1;
+ }
+ zval_ptr_dtor(z);
+ }
+ return 0;
+ } else {
+ return 0;
+ }
+ return 1;
+}
+/* }}} */
+
+ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest) /* {{{ */
+{
+ if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
+ return 0;
+ }
+ return zend_parse_arg_str_weak(arg, dest);
+}
+/* }}} */
+
+static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity) /* {{{ */
{
const char *spec_walk = *spec;
char c = *spec_walk++;
is_null = va_arg(*va, zend_bool *);
}
- if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L', strict)) {
+ if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L')) {
return "integer";
}
}
is_null = va_arg(*va, zend_bool *);
}
- if (!zend_parse_arg_double(arg, p, is_null, check_null, strict)) {
+ if (!zend_parse_arg_double(arg, p, is_null, check_null)) {
return "float";
}
}
{
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
- if (!zend_parse_arg_string(arg, p, pl, check_null, strict)) {
+ if (!zend_parse_arg_string(arg, p, pl, check_null)) {
return "string";
}
}
{
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
- if (!zend_parse_arg_path(arg, p, pl, check_null, strict)) {
+ if (!zend_parse_arg_path(arg, p, pl, check_null)) {
return "a valid path";
}
}
case 'P':
{
zend_string **str = va_arg(*va, zend_string **);
- if (!zend_parse_arg_path_str(arg, str, check_null, strict)) {
+ if (!zend_parse_arg_path_str(arg, str, check_null)) {
return "a valid path";
}
}
case 'S':
{
zend_string **str = va_arg(*va, zend_string **);
- if (!zend_parse_arg_str(arg, str, check_null, strict)) {
+ if (!zend_parse_arg_str(arg, str, check_null)) {
return "string";
}
}
is_null = va_arg(*va, zend_bool *);
}
- if (!zend_parse_arg_bool(arg, p, is_null, check_null, strict)) {
+ if (!zend_parse_arg_bool(arg, p, is_null, check_null)) {
return "boolean";
}
}
break;
} else {
if (is_callable_error) {
- *severity = strict ? (E_EXCEPTION | E_ERROR) : E_WARNING;
+ *severity = E_EXCEPTION | E_ERROR;
zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
efree(is_callable_error);
return "";
}
/* }}} */
-static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int quiet, zend_bool strict) /* {{{ */
+static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int flags) /* {{{ */
{
const char *expected_type = NULL;
char *error = NULL;
int severity;
- expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity, strict);
+ expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity);
if (expected_type) {
- if (!quiet && (*expected_type || error)) {
+ if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) {
const char *space;
const char *class_name = get_active_class_name(&space);
if (error) {
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d %s",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d %s",
class_name, space, get_active_function_name(), arg_num, error);
efree(error);
} else {
- zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be %s, %s given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
class_name, space, get_active_function_name(), arg_num, expected_type,
zend_zval_type_name(arg));
}
{
va_list va;
int ret;
- int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
- zend_bool strict = (flags & ZEND_PARSE_PARAMS_STRICT) ? 1 : 0;
va_start(va, spec);
- ret = zend_parse_arg(arg_num, arg, &va, &spec, quiet, strict);
+ ret = zend_parse_arg(arg_num, arg, &va, &spec, flags);
va_end(va);
return ret;
int post_varargs = 0;
zval *arg;
int arg_count;
- int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
- zend_bool strict = (flags & ZEND_PARSE_PARAMS_STRICT) ? 1 : 0;
zend_bool have_varargs = 0;
zval **varargs = NULL;
int *n_varargs = NULL;
case '*':
case '+':
if (have_varargs) {
- if (!quiet) {
+ if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
break;
default:
- if (!quiet) {
+ if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters",
}
if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) {
- if (!quiet) {
+ if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
- zend_internal_type_error(strict, "%s%s%s() expects %s %d parameter%s, %d given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given",
class_name,
class_name[0] ? "::" : "",
active_function->common.function_name->val,
arg = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
- if (zend_parse_arg(i+1, arg, va, &type_spec, quiet, strict) == FAILURE) {
+ if (zend_parse_arg(i+1, arg, va, &type_spec, flags) == FAILURE) {
/* clean up varargs array if it was used */
if (varargs && *varargs) {
*varargs = NULL;
if (0 == (type_spec)[0] && 0 != __num_args && !(flags & ZEND_PARSE_PARAMS_QUIET)) { \
const char *__space; \
const char * __class_name = get_active_class_name(&__space); \
- zend_internal_type_error((flags & ZEND_PARSE_PARAMS_STRICT), "%s%s%s() expects exactly 0 parameters, %d given", \
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects exactly 0 parameters, %d given", \
__class_name, __space, \
get_active_function_name(), __num_args); \
return FAILURE; \
va_list va;
int retval;
- if (ZEND_ARG_USES_STRICT_TYPES()) {
- flags |= ZEND_PARSE_PARAMS_STRICT;
- }
-
RETURN_IF_ZERO_ARGS(num_args, type_spec, flags);
va_start(va, type_spec);
int retval;
int flags = 0;
- if (ZEND_ARG_USES_STRICT_TYPES()) {
- flags |= ZEND_PARSE_PARAMS_STRICT;
- }
-
RETURN_IF_ZERO_ARGS(num_args, type_spec, flags);
va_start(va, type_spec);
* wrong branch here. */
zend_bool is_method = EG(current_execute_data)->func->common.scope != NULL;
- if (ZEND_ARG_USES_STRICT_TYPES()) {
- flags |= ZEND_PARSE_PARAMS_STRICT;
- }
-
if (!is_method || !this_ptr || Z_TYPE_P(this_ptr) != IS_OBJECT) {
RETURN_IF_ZERO_ARGS(num_args, p, flags);
zval **object;
zend_class_entry *ce;
- if (ZEND_ARG_USES_STRICT_TYPES()) {
- flags |= ZEND_PARSE_PARAMS_STRICT;
- }
-
if (!this_ptr) {
RETURN_IF_ZERO_ARGS(num_args, p, flags);
/* Parameter parsing API -- andrei */
-#define ZEND_PARSE_PARAMS_QUIET (1<<1)
-#define ZEND_PARSE_PARAMS_STRICT (1<<2)
-
+#define ZEND_PARSE_PARAMS_QUIET (1<<1)
ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...);
ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...);
ZEND_API char *zend_zval_type_name(const zval *arg);
ZEND_API int zend_disable_class(char *class_name, size_t class_name_length);
ZEND_API void zend_wrong_param_count(void);
-ZEND_API void zend_wrong_param_count_ex(zend_bool strict);
#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1)
Z_EXPECTED_LAST
} zend_expected_type;
-ZEND_API void zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args, zend_bool strict);
-ZEND_API void zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg, zend_bool strict);
-ZEND_API void zend_wrong_paramer_class_error(int num, char *name, zval *arg, zend_bool strict);
-ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend_bool strict);
+ZEND_API void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args);
+ZEND_API void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg);
+ZEND_API void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg);
+ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error);
#define ZPP_ERROR_OK 0
#define ZPP_ERROR_FAILURE 1
#define ZPP_ERROR_WRONG_COUNT 5
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
- zend_bool _strict = ZEND_ARG_USES_STRICT_TYPES(); \
- const int _flags = (flags) | (_strict ? ZEND_PARSE_PARAMS_STRICT : 0); \
+ const int _flags = (flags); \
int _min_num_args = (min_num_args); \
int _max_num_args = (max_num_args); \
int _num_args = EX_NUM_ARGS(); \
(UNEXPECTED(_num_args > _max_num_args) && \
EXPECTED(_max_num_args >= 0))) { \
if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
- zend_wrong_paramers_count_error(_num_args, _min_num_args, _max_num_args, _strict); \
+ zend_wrong_paramers_count_error(_num_args, _min_num_args, _max_num_args); \
} \
error_code = ZPP_ERROR_FAILURE; \
break; \
if (UNEXPECTED(error_code != ZPP_ERROR_OK)) { \
if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
if (error_code == ZPP_ERROR_WRONG_CALLBACK) { \
- zend_wrong_callback_error(E_WARNING, _i, _error, _strict); \
+ zend_wrong_callback_error(E_WARNING, _i, _error); \
} else if (error_code == ZPP_ERROR_WRONG_CLASS) { \
- zend_wrong_paramer_class_error(_i, _error, _arg, _strict); \
+ zend_wrong_paramer_class_error(_i, _error, _arg); \
} else if (error_code == ZPP_ERROR_WRONG_ARG) { \
- zend_wrong_paramer_type_error(_i, _expected_type, _arg, _strict); \
+ zend_wrong_paramer_type_error(_i, _expected_type, _arg); \
} \
} \
failure; \
/* old "b" */
#define Z_PARAM_BOOL_EX(dest, is_null, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null))) { \
_expected_type = Z_EXPECTED_BOOL; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* old "C" */
#define Z_PARAM_CLASS_EX(dest, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null))) { \
error_code = ZPP_ERROR_FAILURE; \
break; \
}
/* old "d" */
#define Z_PARAM_DOUBLE_EX(dest, is_null, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null))) { \
_expected_type = Z_EXPECTED_DOUBLE; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
break; \
} \
} else if (UNEXPECTED(_error != NULL)) { \
- zend_wrong_callback_error(E_STRICT, _i, _error, _strict); \
+ zend_wrong_callback_error(E_STRICT, _i, _error); \
}
#define Z_PARAM_FUNC(dest_fci, dest_fcc) \
/* old "l" */
#define Z_PARAM_LONG_EX(dest, is_null, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 0, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 0))) { \
_expected_type = Z_EXPECTED_LONG; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* old "L" */
#define Z_PARAM_STRICT_LONG_EX(dest, is_null, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 1, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 1))) { \
_expected_type = Z_EXPECTED_LONG; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* old "p" */
#define Z_PARAM_PATH_EX(dest, dest_len, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null))) { \
_expected_type = Z_EXPECTED_PATH; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* old "P" */
#define Z_PARAM_PATH_STR_EX(dest, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null))) { \
_expected_type = Z_EXPECTED_PATH; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* old "s" */
#define Z_PARAM_STRING_EX(dest, dest_len, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null))) { \
_expected_type = Z_EXPECTED_STRING; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* old "S" */
#define Z_PARAM_STR_EX(dest, check_null, separate) \
Z_PARAM_PROLOGUE(separate); \
- if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null, _strict))) { \
+ if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null))) { \
_expected_type = Z_EXPECTED_STRING; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
/* Inlined implementations shared by new and old parameter parsing APIs */
-ZEND_API int parse_arg_object_to_str(zval *arg, zend_string **str, int type);
-ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null, zend_bool strict);
-
-static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, zend_bool *is_null, int check_null, zend_bool strict)
+ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest);
+ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest);
+
+static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, zend_bool *is_null, int check_null)
{
if (check_null) {
*is_null = 0;
}
if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
*dest = 1;
- } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
- if (check_null) {
- *is_null = (Z_TYPE_P(arg) == IS_NULL);
- } else if (strict && Z_TYPE_P(arg) == IS_NULL) {
- return 0;
- }
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_FALSE)) {
+ *dest = 0;
+ } else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
+ *is_null = 1;
*dest = 0;
- } else if (UNEXPECTED(strict)) {
- return 0;
- } else if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
- *dest = zend_is_true(arg);
} else {
- return 0;
+ return zend_parse_arg_bool_slow(arg, dest);
}
return 1;
}
-static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, zend_bool *is_null, int check_null, int cap, zend_bool strict)
+static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, zend_bool *is_null, int check_null, int cap)
{
if (check_null) {
*is_null = 0;
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*is_null = 1;
*dest = 0;
- } else if (UNEXPECTED(strict)) {
- return 0;
- } else if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
- if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
- return 0;
- }
- if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
- if (cap) {
- *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
- } else {
- return 0;
- }
- } else {
- *dest = zend_dval_to_lval(Z_DVAL_P(arg));
- }
- } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
- double d;
- int type;
-
- if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
- if (EXPECTED(type != 0)) {
- if (UNEXPECTED(zend_isnan(d))) {
- return 0;
- }
- if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
- if (cap) {
- *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
- } else {
- return 0;
- }
- } else {
- *dest = zend_dval_to_lval(d);
- }
- } else {
- return 0;
- }
- }
- } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
- *dest = 0;
- } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
- *dest = 1;
+ } else if (cap) {
+ return zend_parse_arg_long_cap_slow(arg, dest);
} else {
- return 0;
+ return zend_parse_arg_long_slow(arg, dest);
}
return 1;
}
-static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null, zend_bool strict)
+static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null)
{
if (check_null) {
*is_null = 0;
if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
*dest = Z_DVAL_P(arg);
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
- *is_null = 0;
- *dest = 0.0;
- } else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
- /* SSTH Exception: IS_LONG ma be accepted instead as IS_DOUBLE */
- *dest = (double)Z_LVAL_P(arg);
- } else if (UNEXPECTED(strict)) {
- return 0;
- } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
- zend_long l;
- int type;
-
- if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) {
- if (EXPECTED(type != 0)) {
- *dest = (double)(l);
- } else {
- return 0;
- }
- }
- } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
+ *is_null = 1;
*dest = 0.0;
- } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
- *dest = 1.0;
} else {
- return 0;
+ return zend_parse_arg_double_slow(arg, dest);
}
return 1;
}
-static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null, zend_bool strict)
+static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
*dest = Z_STR_P(arg);
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*dest = NULL;
- } else if (UNEXPECTED(strict)) {
- return 0;
- } else if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
- if (Z_COPYABLE_P(arg) && Z_REFCOUNT_P(arg) > 1) {
- Z_DELREF_P(arg);
- zval_copy_ctor_func(arg);
- }
- convert_to_string(arg);
- *dest = Z_STR_P(arg);
- } else if (UNEXPECTED(Z_TYPE_P(arg) != IS_OBJECT) ||
- UNEXPECTED(parse_arg_object_to_str(arg, dest, IS_STRING) != SUCCESS)) {
- return 0;
+ } else {
+ return zend_parse_arg_str_slow(arg, dest);
}
return 1;
}
-static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null, zend_bool strict)
+static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null)
{
zend_string *str;
- if (!zend_parse_arg_str(arg, &str, check_null, strict)) {
+ if (!zend_parse_arg_str(arg, &str, check_null)) {
return 0;
}
if (check_null && UNEXPECTED(!str)) {
return 1;
}
-static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null, zend_bool strict)
+static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null)
{
- if (!zend_parse_arg_str(arg, dest, check_null, strict) ||
+ if (!zend_parse_arg_str(arg, dest, check_null) ||
(*dest && UNEXPECTED(CHECK_NULL_PATH((*dest)->val, (*dest)->len)))) {
return 0;
}
return 1;
}
-static zend_always_inline int zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, int check_null, zend_bool strict)
+static zend_always_inline int zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, int check_null)
{
zend_string *str;
- if (!zend_parse_arg_path_str(arg, &str, check_null, strict)) {
+ if (!zend_parse_arg_path_str(arg, &str, check_null)) {
return 0;
}
if (check_null && UNEXPECTED(!str)) {
static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *arg)
{
- zend_bool strict = 0;
-
switch (type_hint) {
case _IS_BOOL: {
zend_bool dest;
- if (!zend_parse_arg_bool(arg, &dest, NULL, 0, strict)) {
+ if (!zend_parse_arg_bool_weak(arg, &dest)) {
return 0;
}
zval_ptr_dtor(arg);
case IS_LONG: {
zend_long dest;
- if (!zend_parse_arg_long(arg, &dest, NULL, 0, 0, strict)) {
+ if (!zend_parse_arg_long_weak(arg, &dest)) {
return 0;
}
zval_ptr_dtor(arg);
case IS_DOUBLE: {
double dest;
- if (!zend_parse_arg_double(arg, &dest, NULL, 0, strict)) {
+ if (!zend_parse_arg_double_weak(arg, &dest)) {
return 0;
}
zval_ptr_dtor(arg);
zend_string *dest;
/* on success "arg" is converted to IS_STRING */
- if (!zend_parse_arg_str(arg, &dest, 0, strict)) {
+ if (!zend_parse_arg_str_weak(arg, &dest)) {
return 0;
}
return 1;
static zend_bool zend_verify_scalar_type_hint(zend_uchar type_hint, zval *arg, zend_bool strict)
{
if (UNEXPECTED(strict)) {
- /* SSTH Exception: IS_LONG ma be accepted as IS_DOUBLE (converted) */
+ /* SSTH Exception: IS_LONG may be accepted as IS_DOUBLE (converted) */
if (type_hint != IS_DOUBLE || Z_TYPE_P(arg) != IS_LONG) {
return 0;
}
strict = EX_USES_STRICT_TYPES();
do {
if (EXPECTED(!strict)) {
- if (Z_TYPE_P(value) < IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 0);
- break;
- } else if (Z_TYPE_P(value) == IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 1);
- break;
- } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
- zend_string *str = zval_get_string(value);
+ zend_string *str;
+ zval tmp;
+
+ ZVAL_COPY(&tmp, value);
+ if (zend_parse_arg_str_weak(&tmp, &str)) {
ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zend_string_release(str);
+ zval_ptr_dtor(&tmp);
break;
- } else if (Z_TYPE_P(value) == IS_OBJECT) {
- zend_string *str;
- zval tmp;
-
- ZVAL_COPY(&tmp, value);
- if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) {
- ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zval_dtor(&tmp);
- break;
- }
}
+ zval_ptr_dtor(&tmp);
}
zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
ZVAL_NULL(EX_VAR(opline->result.var));
strict = EX_USES_STRICT_TYPES();
do {
if (EXPECTED(!strict)) {
- if (Z_TYPE_P(value) < IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 0);
- break;
- } else if (Z_TYPE_P(value) == IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 1);
- break;
- } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
- zend_string *str = zval_get_string(value);
+ zend_string *str;
+ zval tmp;
+
+ ZVAL_COPY(&tmp, value);
+ if (zend_parse_arg_str_weak(&tmp, &str)) {
ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zend_string_release(str);
+ zval_ptr_dtor(&tmp);
break;
- } else if (Z_TYPE_P(value) == IS_OBJECT) {
- zend_string *str;
- zval tmp;
-
- ZVAL_COPY(&tmp, value);
- if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) {
- ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zval_dtor(&tmp);
- break;
- }
}
+ zval_ptr_dtor(&tmp);
}
zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
ZVAL_NULL(EX_VAR(opline->result.var));
strict = EX_USES_STRICT_TYPES();
do {
if (EXPECTED(!strict)) {
- if (Z_TYPE_P(value) < IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 0);
- break;
- } else if (Z_TYPE_P(value) == IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 1);
- break;
- } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
- zend_string *str = zval_get_string(value);
+ zend_string *str;
+ zval tmp;
+
+ ZVAL_COPY(&tmp, value);
+ if (zend_parse_arg_str_weak(&tmp, &str)) {
ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zend_string_release(str);
+ zval_ptr_dtor(&tmp);
break;
- } else if (Z_TYPE_P(value) == IS_OBJECT) {
- zend_string *str;
- zval tmp;
-
- ZVAL_COPY(&tmp, value);
- if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) {
- ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zval_dtor(&tmp);
- break;
- }
}
+ zval_ptr_dtor(&tmp);
}
zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
ZVAL_NULL(EX_VAR(opline->result.var));
strict = EX_USES_STRICT_TYPES();
do {
if (EXPECTED(!strict)) {
- if (Z_TYPE_P(value) < IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 0);
- break;
- } else if (Z_TYPE_P(value) == IS_TRUE) {
- ZVAL_LONG(EX_VAR(opline->result.var), 1);
- break;
- } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
- zend_string *str = zval_get_string(value);
+ zend_string *str;
+ zval tmp;
+
+ ZVAL_COPY(&tmp, value);
+ if (zend_parse_arg_str_weak(&tmp, &str)) {
ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zend_string_release(str);
+ zval_ptr_dtor(&tmp);
break;
- } else if (Z_TYPE_P(value) == IS_OBJECT) {
- zend_string *str;
- zval tmp;
-
- ZVAL_COPY(&tmp, value);
- if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) {
- ZVAL_LONG(EX_VAR(opline->result.var), str->len);
- zval_dtor(&tmp);
- break;
- }
}
+ zval_ptr_dtor(&tmp);
}
zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
ZVAL_NULL(EX_VAR(opline->result.var));