summaryrefslogtreecommitdiff
path: root/Zend/zend_API.h
diff options
context:
space:
mode:
authorAndrea Faulds <ajf@ajf.me>2015-01-13 00:57:56 +0000
committerAndrea Faulds <ajf@ajf.me>2015-02-10 15:48:06 +0000
commitfe663cc4043cb3f0ea2a528d1c65ef6e21f758c3 (patch)
treeea537abd9707baf5854d21026634ba792b61305c /Zend/zend_API.h
parent02ec3572d91b35032dfe57e93f385dcbe2e12751 (diff)
downloadphp-git-fe663cc4043cb3f0ea2a528d1c65ef6e21f758c3.tar.gz
Partial ZPP strictness implementation
Diffstat (limited to 'Zend/zend_API.h')
-rw-r--r--Zend/zend_API.h95
1 files changed, 58 insertions, 37 deletions
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index d84fbcb2bf..f0270d0847 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -255,7 +255,9 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array);
/* Parameter parsing API -- andrei */
-#define ZEND_PARSE_PARAMS_QUIET (1<<1)
+#define ZEND_PARSE_PARAMS_QUIET (1<<1)
+#define ZEND_PARSE_PARAMS_STRICT (1<<2)
+
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);
@@ -293,7 +295,7 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen
ZEND_API int zend_disable_function(char *function_name, size_t function_name_length);
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(zend_bool strict);
#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1)
@@ -351,12 +353,12 @@ ZEND_API char *zend_get_type_by_const(int type);
#define getThis() (Z_OBJ(EX(This)) ? &EX(This) : NULL)
#define ZEND_IS_METHOD_CALL() (EX(func)->common.scope != NULL)
-#define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT()
-#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret)
+#define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT((ZEND_CALL_INFO(EG(current_execute_data)) & ZEND_CALL_STRICT_TYPEHINTS) ? 1 : 0)
+#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) ZEND_WRONG_PARAM_COUNT_WITH_RETVAL((ZEND_CALL_INFO(EG(current_execute_data)) & ZEND_CALL_STRICT_TYPEHINTS) ? 1 : 0, ret)
#define ARG_COUNT(dummy) EX_NUM_ARGS()
#define ZEND_NUM_ARGS() EX_NUM_ARGS()
-#define ZEND_WRONG_PARAM_COUNT() { zend_wrong_param_count(); return; }
-#define ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret) { zend_wrong_param_count(); return ret; }
+#define ZEND_WRONG_PARAM_COUNT(strict) { zend_wrong_param_count(strict); return; }
+#define ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(strict, ret) { zend_wrong_param_count(strict); return ret; }
#ifndef ZEND_WIN32
#define DLEXPORT
@@ -701,9 +703,9 @@ typedef enum _zend_expected_type {
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_API void zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg);
-ZEND_API void zend_wrong_paramer_class_error(int num, char *name, zval *arg);
+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);
#define ZPP_ERROR_OK 0
@@ -714,7 +716,8 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
#define ZPP_ERROR_WRONG_COUNT 5
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
- const int _flags = (flags); \
+ zend_bool _strict = (EX_CALL_INFO() & ZEND_CALL_STRICT_TYPEHINTS) ? 1 : 0; \
+ const int _flags = (flags) | (_strict ? ZEND_PARSE_PARAMS_STRICT : 0); \
int _min_num_args = (min_num_args); \
int _max_num_args = (max_num_args); \
int _num_args = EX_NUM_ARGS(); \
@@ -738,7 +741,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
(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); \
+ zend_wrong_paramers_count_error(_num_args, _min_num_args, _max_num_args, _strict); \
} \
error_code = ZPP_ERROR_FAILURE; \
break; \
@@ -754,11 +757,11 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
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); \
+ zend_wrong_callback_error(_strict ? E_RECOVERABLE_ERROR : E_WARNING, _i, _error); \
} else if (error_code == ZPP_ERROR_WRONG_CLASS) { \
- zend_wrong_paramer_class_error(_i, _error, _arg); \
+ zend_wrong_paramer_class_error(_i, _error, _arg, _strict); \
} else if (error_code == ZPP_ERROR_WRONG_ARG) { \
- zend_wrong_paramer_type_error(_i, _expected_type, _arg); \
+ zend_wrong_paramer_type_error(_i, _expected_type, _arg, _strict); \
} \
} \
failure; \
@@ -811,7 +814,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null, _strict))) { \
_expected_type = Z_EXPECTED_BOOL; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -823,7 +826,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null, _strict))) { \
error_code = ZPP_ERROR_FAILURE; \
break; \
}
@@ -834,7 +837,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null, _strict))) { \
_expected_type = Z_EXPECTED_DOUBLE; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -889,7 +892,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 0, _strict))) { \
_expected_type = Z_EXPECTED_LONG; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -901,7 +904,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 1, _strict))) { \
_expected_type = Z_EXPECTED_LONG; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -943,7 +946,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null, _strict))) { \
_expected_type = Z_EXPECTED_PATH; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -955,7 +958,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null, _strict))) { \
_expected_type = Z_EXPECTED_PATH; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -979,7 +982,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null, _strict))) { \
_expected_type = Z_EXPECTED_STRING; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -991,7 +994,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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))) { \
+ if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null, _strict))) { \
_expected_type = Z_EXPECTED_STRING; \
error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1046,13 +1049,18 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error);
/* 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_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)
+static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, zend_bool *is_null, int check_null, zend_bool strict)
{
if (check_null) {
*is_null = 0;
}
+
+ if (UNEXPECTED(strict && Z_TYPE_P(arg) != IS_TRUE && Z_TYPE_P(arg) != IS_FALSE && !(check_null && Z_TYPE_P(arg) == IS_NULL))) {
+ return 0;
+ }
+
if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
*dest = 1;
} else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
@@ -1068,11 +1076,16 @@ static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, ze
return 1;
}
-static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, zend_bool *is_null, int check_null, int strict)
+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)
{
if (check_null) {
*is_null = 0;
}
+
+ if (UNEXPECTED(strict && Z_TYPE_P(arg) != IS_LONG && !(check_null && Z_TYPE_P(arg) == IS_NULL))) {
+ return 0;
+ }
+
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
*dest = Z_LVAL_P(arg);
} else if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
@@ -1080,8 +1093,7 @@ static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, ze
return 0;
}
if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
- /* Ironically, the strict parameter makes zpp *non*-strict here */
- if (strict) {
+ if (cap) {
*dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
} else {
return 0;
@@ -1099,7 +1111,7 @@ static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, ze
return 0;
}
if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
- if (strict) {
+ if (cap) {
*dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
} else {
return 0;
@@ -1124,11 +1136,16 @@ static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, ze
return 1;
}
-static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null)
+static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null, zend_bool strict)
{
if (check_null) {
*is_null = 0;
}
+
+ if (UNEXPECTED(strict && Z_TYPE_P(arg) != IS_DOUBLE && !(check_null && Z_TYPE_P(arg) == IS_NULL))) {
+ return 0;
+ }
+
if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
*dest = Z_DVAL_P(arg);
} else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
@@ -1157,8 +1174,12 @@ static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zen
return 1;
}
-static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null)
+static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null, zend_bool strict)
{
+ if (UNEXPECTED(strict && Z_TYPE_P(arg) != IS_STRING && !(check_null && Z_TYPE_P(arg) == IS_NULL))) {
+ return 0;
+ }
+
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
*dest = Z_STR_P(arg);
} else if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
@@ -1179,11 +1200,11 @@ static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest,
return 1;
}
-static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null)
+static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null, zend_bool strict)
{
zend_string *str;
- if (!zend_parse_arg_str(arg, &str, check_null)) {
+ if (!zend_parse_arg_str(arg, &str, check_null, strict)) {
return 0;
}
if (check_null && UNEXPECTED(!str)) {
@@ -1196,20 +1217,20 @@ static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size
return 1;
}
-static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null)
+static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null, zend_bool strict)
{
- if (!zend_parse_arg_str(arg, dest, check_null) ||
+ if (!zend_parse_arg_str(arg, dest, check_null, strict) ||
(*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)
+static zend_always_inline int zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, int check_null, zend_bool strict)
{
zend_string *str;
- if (!zend_parse_arg_path_str(arg, &str, check_null)) {
+ if (!zend_parse_arg_path_str(arg, &str, check_null, strict)) {
return 0;
}
if (check_null && UNEXPECTED(!str)) {