uw                                       Wed, 30 Sep 2009 14:39:33 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=289004

Log:
Fixing a leak in mysqlnd when passing invalid fetch modes to mysqlnd.

Changed paths:
    U   php/php-src/branches/PHP_5_3/ext/mysql/php_mysql.c
    U   php/php-src/branches/PHP_5_3/ext/mysql/tests/mysql_fetch_array.phpt
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
    U   php/php-src/trunk/ext/mysql/php_mysql.c
    U   php/php-src/trunk/ext/mysql/tests/mysql_fetch_array.phpt
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c

Modified: php/php-src/branches/PHP_5_3/ext/mysql/php_mysql.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysql/php_mysql.c  2009-09-30 14:34:32 UTC 
(rev 289003)
+++ php/php-src/branches/PHP_5_3/ext/mysql/php_mysql.c  2009-09-30 14:39:33 UTC 
(rev 289004)
@@ -1972,7 +1972,7 @@
                }
        }

-       if ((result_type & MYSQL_BOTH) == 0) {
+       if (result_type & ~MYSQL_BOTH) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type 
should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
                result_type = MYSQL_BOTH;
        }
@@ -2149,6 +2149,11 @@
        }
        ZEND_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, -1, "MySQL 
result", le_result);

+       if (mode & ~MYSQL_BOTH) {
+                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type 
should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
+                mode = MYSQL_BOTH;
+        }
+
        mysqlnd_fetch_into(result, mode, return_value, MYSQLND_MYSQL);
 #endif
 }

Modified: php/php-src/branches/PHP_5_3/ext/mysql/tests/mysql_fetch_array.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysql/tests/mysql_fetch_array.phpt 
2009-09-30 14:34:32 UTC (rev 289003)
+++ php/php-src/branches/PHP_5_3/ext/mysql/tests/mysql_fetch_array.phpt 
2009-09-30 14:39:33 UTC (rev 289004)
@@ -56,7 +56,7 @@
 do {
        $illegal_mode = mt_rand(0, 10000);
 } while (in_array($illegal_mode, array(MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH)));
-$tmp = @mysql_fetch_array($res, $illegal_mode);
+$tmp = mysql_fetch_array($res, $illegal_mode);
 if (!is_array($tmp))
        printf("[013] Expecting array, got %s/%s. [%d] %s\n",
                gettype($tmp), $tmp, mysql_errno($link), mysql_error($link));
@@ -355,5 +355,7 @@
   %unicode|string%(1) "1"
 }

+Warning: mysql_fetch_array(): The result type should be either MYSQL_NUM, 
MYSQL_ASSOC or MYSQL_BOTH in %s on line %d
+
 Warning: mysql_fetch_array(): %d is not a valid MySQL result resource in %s on 
line %d
 done!

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c   2009-09-30 
14:34:32 UTC (rev 289003)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c   2009-09-30 
14:39:33 UTC (rev 289004)
@@ -901,13 +901,8 @@
                                        lengths[i] = len;
                                }

-                               /* Forbid ZE to free it, we will clean it */
-                               Z_ADDREF_P(data);
-
-                               if ((flags & MYSQLND_FETCH_BOTH) == 
MYSQLND_FETCH_BOTH) {
-                                       Z_ADDREF_P(data);
-                               }
                                if (flags & MYSQLND_FETCH_NUM) {
+                                       Z_ADDREF_P(data);
                                        zend_hash_next_index_insert(row_ht, 
&data, sizeof(zval *), NULL);
                                }
                                if (flags & MYSQLND_FETCH_ASSOC) {
@@ -918,6 +913,7 @@
                                          the index is a numeric and convert it 
to it. This however means constant
                                          hashing of the column name, which is 
not needed as it can be precomputed.
                                        */
+                                       Z_ADDREF_P(data);
                                        if (zend_hash_key->is_numeric == FALSE) 
{
 #if PHP_MAJOR_VERSION >= 6
                                                
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
@@ -1128,16 +1124,8 @@
                for (i = 0; i < result->field_count; i++, field++, 
zend_hash_key++) {
                        zval *data = current_row[i];

-                       /*
-                         Let us later know what to do with this zval. If 
ref_count > 1, we will just
-                         decrease it, otherwise free it. zval_ptr_dtor() make 
this very easy job.
-                       */
-                       Z_ADDREF_P(data);
-
-                       if ((flags & MYSQLND_FETCH_BOTH) == MYSQLND_FETCH_BOTH) 
{
-                               Z_ADDREF_P(data);
-                       }
                        if (flags & MYSQLND_FETCH_NUM) {
+                               Z_ADDREF_P(data);
                                zend_hash_next_index_insert(Z_ARRVAL_P(row), 
&data, sizeof(zval *), NULL);
                        }
                        if (flags & MYSQLND_FETCH_ASSOC) {
@@ -1148,6 +1136,7 @@
                                  the index is a numeric and convert it to it. 
This however means constant
                                  hashing of the column name, which is not 
needed as it can be precomputed.
                                */
+                               Z_ADDREF_P(data);
                                if (zend_hash_key->is_numeric == FALSE) {
 #if PHP_MAJOR_VERSION >= 6
                                        
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,

Modified: php/php-src/trunk/ext/mysql/php_mysql.c
===================================================================
--- php/php-src/trunk/ext/mysql/php_mysql.c     2009-09-30 14:34:32 UTC (rev 
289003)
+++ php/php-src/trunk/ext/mysql/php_mysql.c     2009-09-30 14:39:33 UTC (rev 
289004)
@@ -2012,7 +2012,7 @@
                }
        }

-       if ((result_type & MYSQL_BOTH) == 0) {
+       if (result_type & ~MYSQL_BOTH) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type 
should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
                result_type = MYSQL_BOTH;
        }
@@ -2200,6 +2200,11 @@
        }
        ZEND_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, -1, "MySQL 
result", le_result);

+       if (mode & ~MYSQL_BOTH) {
+                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type 
should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
+                mode = MYSQL_BOTH;
+        }
+
        mysqlnd_fetch_into(result, mode, return_value, MYSQLND_MYSQL);
 #endif
 }

Modified: php/php-src/trunk/ext/mysql/tests/mysql_fetch_array.phpt
===================================================================
--- php/php-src/trunk/ext/mysql/tests/mysql_fetch_array.phpt    2009-09-30 
14:34:32 UTC (rev 289003)
+++ php/php-src/trunk/ext/mysql/tests/mysql_fetch_array.phpt    2009-09-30 
14:39:33 UTC (rev 289004)
@@ -56,7 +56,7 @@
 do {
        $illegal_mode = mt_rand(0, 10000);
 } while (in_array($illegal_mode, array(MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH)));
-$tmp = @mysql_fetch_array($res, $illegal_mode);
+$tmp = mysql_fetch_array($res, $illegal_mode);
 if (!is_array($tmp))
        printf("[013] Expecting array, got %s/%s. [%d] %s\n",
                gettype($tmp), $tmp, mysql_errno($link), mysql_error($link));
@@ -355,5 +355,7 @@
   %unicode|string%(1) "1"
 }

+Warning: mysql_fetch_array(): The result type should be either MYSQL_NUM, 
MYSQL_ASSOC or MYSQL_BOTH in %s on line %d
+
 Warning: mysql_fetch_array(): %d is not a valid MySQL result resource in %s on 
line %d
 done!

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c      2009-09-30 14:34:32 UTC 
(rev 289003)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c      2009-09-30 14:39:33 UTC 
(rev 289004)
@@ -901,13 +901,8 @@
                                        lengths[i] = len;
                                }

-                               /* Forbid ZE to free it, we will clean it */
-                               Z_ADDREF_P(data);
-
-                               if ((flags & MYSQLND_FETCH_BOTH) == 
MYSQLND_FETCH_BOTH) {
-                                       Z_ADDREF_P(data);
-                               }
                                if (flags & MYSQLND_FETCH_NUM) {
+                                       Z_ADDREF_P(data);
                                        zend_hash_next_index_insert(row_ht, 
&data, sizeof(zval *), NULL);
                                }
                                if (flags & MYSQLND_FETCH_ASSOC) {
@@ -918,6 +913,7 @@
                                          the index is a numeric and convert it 
to it. This however means constant
                                          hashing of the column name, which is 
not needed as it can be precomputed.
                                        */
+                                       Z_ADDREF_P(data);
                                        if (zend_hash_key->is_numeric == FALSE) 
{
 #if PHP_MAJOR_VERSION >= 6
                                                
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
@@ -1128,16 +1124,8 @@
                for (i = 0; i < result->field_count; i++, field++, 
zend_hash_key++) {
                        zval *data = current_row[i];

-                       /*
-                         Let us later know what to do with this zval. If 
ref_count > 1, we will just
-                         decrease it, otherwise free it. zval_ptr_dtor() make 
this very easy job.
-                       */
-                       Z_ADDREF_P(data);
-
-                       if ((flags & MYSQLND_FETCH_BOTH) == MYSQLND_FETCH_BOTH) 
{
-                               Z_ADDREF_P(data);
-                       }
                        if (flags & MYSQLND_FETCH_NUM) {
+                               Z_ADDREF_P(data);
                                zend_hash_next_index_insert(Z_ARRVAL_P(row), 
&data, sizeof(zval *), NULL);
                        }
                        if (flags & MYSQLND_FETCH_ASSOC) {
@@ -1148,6 +1136,7 @@
                                  the index is a numeric and convert it to it. 
This however means constant
                                  hashing of the column name, which is not 
needed as it can be precomputed.
                                */
+                               Z_ADDREF_P(data);
                                if (zend_hash_key->is_numeric == FALSE) {
 #if PHP_MAJOR_VERSION >= 6
                                        
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to