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