]> granicus.if.org Git - php/commitdiff
Fix #61704 (Crash apache, phpinfo() threading issue)
authorJohannes Schlüter <johannes@php.net>
Tue, 8 May 2012 15:30:05 +0000 (17:30 +0200)
committerJohannes Schlüter <johannes@php.net>
Tue, 8 May 2012 15:30:05 +0000 (17:30 +0200)
NEWS
ext/mysqlnd/mysqlnd_plugin.c
ext/mysqlnd/php_mysqlnd.c

diff --git a/NEWS b/NEWS
index f88bf70aeccaeeaf1ca9e7c2f118306e8595a3c6..6008f42d1fec5df75acaefa929ea9da98f4da83d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -110,6 +110,7 @@ PHP                                                                        NEWS
   . Fixed bug #61003 (mysql_stat() require a valid connection). (Johannes).
 
 - mysqlnd
+  . Fixed bug #61704 (Crash apache, phpinfo() threading issue). (Johannes)
   . Fixed bug #60948 (mysqlnd FTBFS when -Wformat-security is enabled).
     (Johannes)
 
index 457596feabe15442512f1274a01befa9815d2c5f..2dbb57d1c8d5ab2ad4355ee932f93ef3b847e84c 100644 (file)
@@ -169,7 +169,24 @@ PHPAPI void * _mysqlnd_plugin_find(const char * const name TSRMLS_DC)
 /* {{{ _mysqlnd_plugin_apply_with_argument */
 PHPAPI void _mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, void * argument TSRMLS_DC)
 {
-       zend_hash_apply_with_argument(&mysqlnd_registered_plugins, apply_func, argument TSRMLS_CC);
+       /* Note: We want to be thread-safe (read-only), so we can use neither
+        * zend_hash_apply_with_argument nor zend_hash_internal_pointer_reset and
+        * friends
+        */
+       Bucket *p;
+
+       p = mysqlnd_registered_plugins.pListHead;
+       while (p != NULL) {
+               int result = apply_func(p->pData, argument TSRMLS_CC);
+
+               if (result & ZEND_HASH_APPLY_REMOVE) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "mysqlnd_plugin_apply_with_argument must not remove table entries");
+               }
+               p = p->pListNext;
+               if (result & ZEND_HASH_APPLY_STOP) {
+                       break;
+               }
+       }
 }
 /* }}} */
 
index 1022285ad72c7d9783a063640bdc38561d03ca4b..20fcc5e7adb8d3c15c114878bd7a0b2dd1e77b9c 100644 (file)
@@ -135,16 +135,22 @@ mysqlnd_minfo_dump_loaded_plugins(void *pDest, void * buf TSRMLS_DC)
 /* }}} */
 
 /* {{{ mysqlnd_minfo_dump_api_plugins */
-static int
-mysqlnd_minfo_dump_api_plugins(void * pDest, void * buf TSRMLS_DC)
+static void
+mysqlnd_minfo_dump_api_plugins(smart_str * buffer TSRMLS_DC)
 {
-       smart_str * buffer = (smart_str *) buf;
-       MYSQLND_REVERSE_API * ext = *(MYSQLND_REVERSE_API **) pDest;
-       if (buffer->len) {
-               smart_str_appendc(buffer, ',');
+       HashTable *ht = mysqlnd_reverse_api_get_api_list(TSRMLS_C);
+       Bucket *p;
+
+       p = ht->pListHead;
+       while(p != NULL) {
+               MYSQLND_REVERSE_API * ext = *(MYSQLND_REVERSE_API **) p->pData;
+               if (buffer->len) {
+                       smart_str_appendc(buffer, ',');
+               }
+               smart_str_appends(buffer, ext->module->name);
+
+               p = p->pListNext;
        }
-       smart_str_appends(buffer, ext->module->name);
-       return ZEND_HASH_APPLY_KEEP;
 }
 /* }}} */
 
@@ -189,7 +195,7 @@ PHP_MINFO_FUNCTION(mysqlnd)
                php_info_print_table_row(2, "Loaded plugins", tmp_str.c);
                smart_str_free(&tmp_str);
 
-               zend_hash_apply_with_argument(mysqlnd_reverse_api_get_api_list(TSRMLS_C), mysqlnd_minfo_dump_api_plugins, &tmp_str TSRMLS_CC);
+               mysqlnd_minfo_dump_api_plugins(&tmp_str TSRMLS_CC);
                smart_str_0(&tmp_str);
                php_info_print_table_row(2, "API Extensions", tmp_str.c);
                smart_str_free(&tmp_str);