这个问题是我在无意中发现的,
函数源代码
PHP_FUNCTION(str_repeat)
{
zend_string *input_str;
zend_long mult; //这个是int32
zend_string *result; /* Resulting string */
size_t result_len; /* Length of the resulting string */
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sl", &input_str, &mult) == FAILURE) {
return;
}
if (mult < 0) {
php_error_docref(NULL, E_WARNING, "Second argument has to be greater than or equal to 0");
return;
}
/* Don't waste our time if it's empty */
/* ... or if the multiplier is zero */
if (ZSTR_LEN(input_str) == 0 || mult == 0)
RETURN_EMPTY_STRING();
/* Initialize the result string */
result = zend_string_safe_alloc(ZSTR_LEN(input_str), mult, 0, 0); 这里内存申请跟safe_emalloc差不多
result_len = ZSTR_LEN(input_str) * mult;
/* Heavy optimization for situations where input string is 1 byte long */
if (ZSTR_LEN(input_str) == 1) {
memset(ZSTR_VAL(result), *ZSTR_VAL(input_str), mult);
} else {
char *s, *e, *ee;
ptrdiff_t l=0;
memcpy(ZSTR_VAL(result), ZSTR_VAL(input_str), ZSTR_LEN(input_str));
s = ZSTR_VAL(result);
e = ZSTR_VAL(result) + ZSTR_LEN(input_str);
ee = ZSTR_VAL(result) + result_len;
while (e<ee) {
l = (e-s) < (ee-e) ? (e-s) : (ee-e);
memmove(e, s, l);
e += l;
}
}
ZSTR_VAL(result)[result_len] = '\0';
RETURN_NEW_STR(result);
}
我想问的是safe_emalloc能够对整数溢出起到保护作用么而不是单单的提醒作用吗。内存申请为什么是mult*ZSTR_LEN(input_str)+24,而不是mult*ZSTR_LEN(input_str)+0
运行后的结果
C:\Users\admin\Desktop\php-7.0.13-nts-Win32-VC14-x86>php test.php
PHP Fatal error: Possible integer overflow in memory allocation (26 * 165191049
+ 24) in C:\Users\admin\Desktop\php-7.0.13-nts-Win32-VC14-x86\test.php on line
3
PHP Stack trace:
PHP 1. {main}() C:\Users\admin\Desktop\php-7.0.13-nts-Win32-VC14-x86\test.php:
0
PHP 2. str_repeat() C:\Users\admin\Desktop\php-7.0.13-nts-Win32-VC14-x86\test.
php:3
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!