]> granicus.if.org Git - php/commitdiff
Fixed bug Bug #70895 null ptr deref and segfault
authorAnatol Belski <ab@php.net>
Wed, 11 Nov 2015 23:52:36 +0000 (00:52 +0100)
committerAnatol Belski <ab@php.net>
Wed, 11 Nov 2015 23:52:36 +0000 (00:52 +0100)
Zend/tests/bug70895.phpt [new file with mode: 0644]
Zend/zend_API.c

diff --git a/Zend/tests/bug70895.phpt b/Zend/tests/bug70895.phpt
new file mode 100644 (file)
index 0000000..e6df09c
--- /dev/null
@@ -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+
index 5a488f7e9d662fa1ad79f19629e4fee2f69ccee6..0abaccd3ec792dd07d0aa103b259510d44bdd7ac 100644 (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;
        }