Fixed bug Bug #70895 null ptr deref and segfault

This commit is contained in:
Anatol Belski 2015-11-12 00:52:36 +01:00
parent a2e59e72bc
commit 8eef11d317
2 changed files with 37 additions and 1 deletions

15
Zend/tests/bug70895.phpt Normal file
View File

@ -0,0 +1,15 @@
--TEST--
Bug #70895 null ptr deref and segfault with crafted calable
--FILE--
<?php
array_map("%n", 0);
array_map("%n %i", 0);
array_map("%n %i aoeu %f aoeu %p", 0);
?>
--EXPECTREGEX--
Warning: array_map\(\) expects parameter 1 to be a valid callback, function '%n' not found or invalid function name in .+
Warning: array_map\(\) expects parameter 1 to be a valid callback, function '%n %i' not found or invalid function name in .+
Warning: array_map\(\) expects parameter 1 to be a valid callback, function '%n %i aoeu %f aoeu %p' not found or invalid function name in .+bug70895.php on line \d+

View File

@ -2989,7 +2989,28 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
} else {
/* We already checked for plain function before. */
if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
size_t callable_name_len = Z_STRLEN_P(callable), sanitized_callable_name_len = Z_STRLEN_P(callable), k = 0, n = 0;
char *callable_name = Z_STRVAL_P(callable), *sanitized_callable_name = emalloc(sizeof(char) * callable_name_len);
while (k < callable_name_len) {
sanitized_callable_name[n] = callable_name[k];
if ('%' == callable_name[k]) {
n++;
sanitized_callable_name[n] = '%';
}
k++;
n++;
if (n == sanitized_callable_name_len) {
sanitized_callable_name_len += callable_name_len - k;
sanitized_callable_name = erealloc(sanitized_callable_name, sanitized_callable_name_len);
}
}
sanitized_callable_name[n] = '\0';
zend_spprintf(error, 0, "function '%s' not found or invalid function name", sanitized_callable_name);
efree(sanitized_callable_name);
}
return 0;
}