diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d72fc7369aff7..62c4fd4b9265a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -628,6 +628,17 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva } } else if (cur_arg_info->type_hint) { switch(cur_arg_info->type_hint) { + case IS_LONG: + if (!arg) { + return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type long", "", "none", "" TSRMLS_CC); + } + + if (Z_TYPE_P(arg) != IS_LONG && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) + && (Z_TYPE_P(arg) != IS_STRING || is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0)) == 0) { + return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type long", "", zend_zval_type_name(arg), "" TSRMLS_CC); + } + break; + case IS_ARRAY: if (!arg) { return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 0d2b53a7ca929..2790f2a3faf4d 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -325,14 +325,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substr, 0, 0, 2) ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, start) - ZEND_ARG_INFO(0, length) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 1) ZEND_ARG_INFO(0, encoding) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strcut, 0, 0, 2) ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, start) - ZEND_ARG_INFO(0, length) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 1) ZEND_ARG_INFO(0, encoding) ZEND_END_ARG_INFO() @@ -2714,10 +2714,11 @@ PHP_FUNCTION(mb_substr) size_t argc = ZEND_NUM_ARGS(); char *str, *encoding; long from, len; + zval *zlen = NULL; int mblen, str_len, encoding_len; mbfl_string string, result, *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", &str, &str_len, &from, &len, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|z!s", &str, &str_len, &from, &zlen, &encoding, &encoding_len) == FAILURE) { return; } @@ -2736,8 +2737,10 @@ PHP_FUNCTION(mb_substr) string.val = (unsigned char *)str; string.len = str_len; - if (argc < 3) { + if (argc < 3 || !zlen) { len = str_len; + } else { + len = Z_LVAL_P(zlen); } /* measures length */ @@ -2787,6 +2790,7 @@ PHP_FUNCTION(mb_strcut) size_t argc = ZEND_NUM_ARGS(); char *encoding; long from, len; + zval *zlen = NULL; int encoding_len; mbfl_string string, result, *ret; @@ -2794,7 +2798,7 @@ PHP_FUNCTION(mb_strcut) string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", (char **)&string.val, (int **)&string.len, &from, &len, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|z!s", (char **)&string.val, (int **)&string.len, &from, &zlen, &encoding, &encoding_len) == FAILURE) { return; } @@ -2806,8 +2810,10 @@ PHP_FUNCTION(mb_strcut) } } - if (argc < 3) { + if (argc < 3 || !zlen) { len = string.len; + } else { + len = Z_LVAL_P(zlen); } /* if "from" position is negative, count start position from the end diff --git a/ext/mbstring/tests/mb_str_functions_opt-parameter.phpt b/ext/mbstring/tests/mb_str_functions_opt-parameter.phpt index e4a235df308d7..5fb642f9b2ef3 100644 --- a/ext/mbstring/tests/mb_str_functions_opt-parameter.phpt +++ b/ext/mbstring/tests/mb_str_functions_opt-parameter.phpt @@ -28,5 +28,3 @@ baz baz foo ==DONE== ---XFAIL-- -mb functions fail to allow null instead of actual value