--- /dev/null
+--TEST--
+Scalar type hint - internal function strict mode
+--FILE--
+<?php
+declare(strict_types=1);
+
+echo "*** Trying Ord With Integer" . PHP_EOL;
+try {
+ var_dump(ord(1));
+} catch (TypeException $e) {
+ echo "*** Caught " . $e->getMessage() . PHP_EOL;
+}
+
+echo "*** Trying Array Map With Invalid Callback" . PHP_EOL;
+try {
+ array_map([null, "bar"], []);
+} catch (TypeException $e) {
+ echo "*** Caught " . $e->getMessage() . PHP_EOL;
+}
+
+echo "*** Trying Strlen With Float" . PHP_EOL;
+try {
+ var_dump(strlen(1.5));
+} catch (TypeException $e) {
+ echo "*** Caught " . $e->getMessage() . PHP_EOL;
+}
+
+?>
+--EXPECTF--
+*** Trying Ord With Integer
+*** Caught ord() expects parameter 1 to be string, integer given
+*** Trying Array Map With Invalid Callback
+*** Caught array_map() expects parameter 1 to be a valid callback, first array member is not a valid class name or object
+*** Trying Strlen With Float
+*** Caught strlen() expects parameter 1 to be string, float given
\ No newline at end of file
}
/* }}} */
-ZEND_API void zend_wrong_callback_error(int severity, int num, char *error) /* {{{ */
+ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend_bool strict) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
- zend_error(severity, "%s%s%s() expects parameter %d to be a valid callback, %s",
- class_name, space, get_active_function_name(), num, error);
+ if (severity == E_WARNING) {
+ zend_internal_type_error(strict, "%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",
+ class_name, space, get_active_function_name(), num, error);
+ }
efree(error);
}
/* }}} */
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_API void zend_wrong_callback_error(int severity, int num, char *error, zend_bool strict);
#define ZPP_ERROR_OK 0
#define ZPP_ERROR_FAILURE 1
if (UNEXPECTED(error_code != ZPP_ERROR_OK)) { \
if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
if (error_code == ZPP_ERROR_WRONG_CALLBACK) { \
- zend_wrong_callback_error(_strict ? E_RECOVERABLE_ERROR : E_WARNING, _i, _error); \
+ zend_wrong_callback_error(E_WARNING, _i, _error, _strict); \
} else if (error_code == ZPP_ERROR_WRONG_CLASS) { \
zend_wrong_paramer_class_error(_i, _error, _arg, _strict); \
} else if (error_code == ZPP_ERROR_WRONG_ARG) { \
break; \
} \
} else if (UNEXPECTED(_error != NULL)) { \
- zend_wrong_callback_error(E_STRICT, _i, _error); \
+ zend_wrong_callback_error(E_STRICT, _i, _error, _strict); \
}
#define Z_PARAM_FUNC(dest_fci, dest_fcc) \
ZEND_VM_C_LABEL(try_strlen):
if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
- } else {
+ } else if (EXPECTED(0 == EX_USES_STRICT_TYPES())) {
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
ZEND_VM_C_GOTO(try_strlen);
zend_error(E_WARNING, "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));
}
+ } else {
+ zend_type_error("strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
}
FREE_OP1();
CHECK_EXCEPTION();
try_strlen:
if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
- } else {
+ } else if (EXPECTED(0 == EX_USES_STRICT_TYPES())) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
goto try_strlen;
zend_error(E_WARNING, "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));
}
+ } else {
+ zend_type_error("strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
}
CHECK_EXCEPTION();
try_strlen:
if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
- } else {
+ } else if (EXPECTED(0 == EX_USES_STRICT_TYPES())) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
goto try_strlen;
zend_error(E_WARNING, "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));
}
+ } else {
+ zend_type_error("strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
}
CHECK_EXCEPTION();
try_strlen:
if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
- } else {
+ } else if (EXPECTED(0 == EX_USES_STRICT_TYPES())) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
goto try_strlen;
zend_error(E_WARNING, "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));
}
+ } else {
+ zend_type_error("strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
}
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();