]> granicus.if.org Git - php/commitdiff
MFH: - Fixed bug #32647 (Using register_shutdown_function() with invalid callback...
authorfoobar <sniper@php.net>
Thu, 21 Apr 2005 14:47:13 +0000 (14:47 +0000)
committerfoobar <sniper@php.net>
Thu, 21 Apr 2005 14:47:13 +0000 (14:47 +0000)
NEWS
ext/standard/basic_functions.c

diff --git a/NEWS b/NEWS
index 3d140c3243e10137fb433756778df60658bc443b..21d67e44efee693e5fbc9cd40c6bca016e3600fd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP 4                                                                      NEWS
   (Derick)
 - Fixed bug #32682 (ext/mssql: Error on module shutdown when called from 
   activescript). (Frank)
+- Fixed bug #32647 (Using register_shutdown_function() with invalid callback
+  can crash PHP). (Jani)
 - Fixed bug #32591 (ext/mysql: Unsatisfied symbol: ntohs with HP-UX). (Jani)
 - Fixed bug #32589 (Possible crash inside imap_mail_compose, with charsets).
   (Ilia)
index 8904dbdc6b7ec944433d19979f230f567f4c697c..7ef15f34e404cad2026c0c43a184e54ace2c0824 100644 (file)
@@ -2089,17 +2089,21 @@ void user_tick_function_dtor(user_tick_function_entry *tick_function_entry)
 static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC)
 {
        zval retval;
-
-       if (call_user_function( EG(function_table), NULL,
-                                                       shutdown_function_entry->arguments[0],
-                                                       &retval, 
-                                                       shutdown_function_entry->arg_count - 1,
-                                                       shutdown_function_entry->arguments + 1 
-                                                       TSRMLS_CC ) == SUCCESS ) {
+       char *function_name = NULL;
+
+       if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
+               php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
+       } else if (call_user_function(EG(function_table), NULL,
+                                                               shutdown_function_entry->arguments[0],
+                                                               &retval, 
+                                                               shutdown_function_entry->arg_count - 1,
+                                                               shutdown_function_entry->arguments + 1 
+                                                               TSRMLS_CC ) == SUCCESS)
+       {
                zval_dtor(&retval);
-
-       } else {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0]));
+       } 
+       if (function_name) {
+               efree(function_name);
        }
        return 0;
 }
@@ -2192,6 +2196,7 @@ void php_free_shutdown_functions(TSRMLS_D)
 PHP_FUNCTION(register_shutdown_function)
 {
        php_shutdown_function_entry shutdown_function_entry;
+       char *function_name = NULL;
        int i;
 
        shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
@@ -2200,26 +2205,31 @@ PHP_FUNCTION(register_shutdown_function)
                WRONG_PARAM_COUNT;
        }
 
-       shutdown_function_entry.arguments = (pval **) safe_emalloc(sizeof(pval *), shutdown_function_entry.arg_count, 0);
+       shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
 
        if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
                RETURN_FALSE;
        }
        
-       /* Prevent entering of anything but arrays/strings */
-       if (Z_TYPE_P(shutdown_function_entry.arguments[0]) != IS_ARRAY) {
-               convert_to_string(shutdown_function_entry.arguments[0]);
-       }
-       
-       if (!BG(user_shutdown_function_names)) {
-               ALLOC_HASHTABLE(BG(user_shutdown_function_names));
-               zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0);
-       }
+       /* Prevent entering of anything but valid callback (syntax check only!) */
+       if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", function_name);
+               efree(shutdown_function_entry.arguments);
+               RETVAL_FALSE;
+       } else {
+               if (!BG(user_shutdown_function_names)) {
+                       ALLOC_HASHTABLE(BG(user_shutdown_function_names));
+                       zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0);
+               }
 
-       for (i = 0; i < shutdown_function_entry.arg_count; i++) {
-               shutdown_function_entry.arguments[i]->refcount++;
+               for (i = 0; i < shutdown_function_entry.arg_count; i++) {
+                       shutdown_function_entry.arguments[i]->refcount++;
+               }
+               zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
+       }
+       if (function_name) {
+               efree(function_name);
        }
-       zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
 }
 /* }}} */