* Fixed bug #24535 (Crash when retrieving data from unbuffered result after

the original connection has been changed).
* Fixed a crash when trying to fetch an unbuffered result after
mysql_close() has been called.
* Added a check to make sure no unbuffered results are inside the buffer
when calling functions that internally execute a query. Affected functions
are: mysql_select_db(), mysql_list_dbs(), mysql_list_tables(),
mysql_list_processes(), mysql_list_fields(), mysql_stat() and mysql_ping().
* Do not re-select a database if the database to be selected is the same.
This commit is contained in:
Ilia Alshanetsky 2003-07-22 16:05:32 +00:00
parent 4ec05c508b
commit 5fcff2d872

View File

@ -222,6 +222,26 @@ void timeout(int sig);
#define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } } #define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } }
#define PHPMY_UNBUFFERED_QUERY_CHECK() \
{ \
if (mysql->active_result_id) { \
do { \
int type; \
MYSQL_RES *mysql_result; \
\
mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type); \
if (mysql_result && type==le_result) { \
if (!mysql_eof(mysql_result)) { \
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
while (mysql_fetch_row(mysql_result)); \
} \
zend_list_delete(mysql->active_result_id); \
mysql->active_result_id = 0; \
} \
} while(0); \
} \
} \
/* {{{ _free_mysql_result /* {{{ _free_mysql_result
* This wrapper is required since mysql_free_result() returns an integer, and * This wrapper is required since mysql_free_result() returns an integer, and
* thus, cannot be used directly * thus, cannot be used directly
@ -239,14 +259,30 @@ static void _free_mysql_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
*/ */
static void php_mysql_set_default_link(int id TSRMLS_DC) static void php_mysql_set_default_link(int id TSRMLS_DC)
{ {
if (MySG(default_link)!=-1) {
zend_list_delete(MySG(default_link));
}
MySG(default_link) = id; MySG(default_link) = id;
zend_list_addref(id); zend_list_addref(id);
} }
/* }}} */ /* }}} */
/* {{{ php_mysql_select_db
*/
static int php_mysql_select_db(php_mysql_conn *mysql, char *db TSRMLS_DC)
{
/* a small optimization to avoid selecting the database if it is already selected */
if (mysql->conn.db && !strcmp(mysql->conn.db, db)) {
return 1;
} else {
PHPMY_UNBUFFERED_QUERY_CHECK();
if (mysql_select_db(&mysql->conn, db) != 0) {
return 0;
} else {
return 1;
}
}
}
/* }}} */
/* {{{ _close_mysql_link /* {{{ _close_mysql_link
*/ */
static void _close_mysql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) static void _close_mysql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
@ -833,11 +869,13 @@ PHP_FUNCTION(mysql_close)
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
if (id==-1) { /* explicit resource number */ if (id==-1) { /* explicit resource number */
PHPMY_UNBUFFERED_QUERY_CHECK();
zend_list_delete(Z_RESVAL_PP(mysql_link)); zend_list_delete(Z_RESVAL_PP(mysql_link));
} }
if (id!=-1 if (id!=-1
|| (mysql_link && Z_RESVAL_PP(mysql_link)==MySG(default_link))) { || (mysql_link && Z_RESVAL_PP(mysql_link)==MySG(default_link))) {
PHPMY_UNBUFFERED_QUERY_CHECK();
zend_list_delete(MySG(default_link)); zend_list_delete(MySG(default_link));
MySG(default_link) = -1; MySG(default_link) = -1;
} }
@ -877,10 +915,10 @@ PHP_FUNCTION(mysql_select_db)
convert_to_string_ex(db); convert_to_string_ex(db);
if (mysql_select_db(&mysql->conn, Z_STRVAL_PP(db))!=0) { if (php_mysql_select_db(mysql, Z_STRVAL_PP(db) TSRMLS_CC)) {
RETVAL_FALSE; RETURN_TRUE;
} else { } else {
RETVAL_TRUE; RETURN_FALSE;
} }
} }
/* }}} */ /* }}} */
@ -1057,6 +1095,8 @@ PHP_FUNCTION(mysql_stat)
} }
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
PHPMY_UNBUFFERED_QUERY_CHECK();
RETURN_STRING((char *)mysql_stat(&mysql->conn), 1); RETURN_STRING((char *)mysql_stat(&mysql->conn), 1);
} }
/* }}} */ /* }}} */
@ -1116,9 +1156,10 @@ PHP_FUNCTION(mysql_create_db)
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "This function is deprecated, please use mysql_query() to issue a SQL CREATE DATABASE statement instead."); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "This function is deprecated, please use mysql_query() to issue a SQL CREATE DATABASE statement instead.");
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
PHPMY_UNBUFFERED_QUERY_CHECK();
convert_to_string_ex(db); convert_to_string_ex(db);
if (mysql_create_db(&mysql->conn, Z_STRVAL_PP(db))==0) { if (mysql_create_db(&mysql->conn, Z_STRVAL_PP(db))==0) {
@ -1184,26 +1225,12 @@ static void php_mysql_do_query_general(zval **query, zval **mysql_link, int link
if (db) { if (db) {
convert_to_string_ex(db); convert_to_string_ex(db);
if (mysql_select_db(&mysql->conn, Z_STRVAL_PP(db))!=0) { if (!php_mysql_select_db(mysql, Z_STRVAL_PP(db) TSRMLS_CC)) {
RETURN_FALSE; RETURN_FALSE;
} }
} }
PHPMY_UNBUFFERED_QUERY_CHECK();
if (mysql->active_result_id) do {
int type;
MYSQL_RES *mysql_result;
mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type);
if (mysql_result && type==le_result) {
if (!mysql_eof(mysql_result)) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query");
while (mysql_fetch_row(mysql_result));
}
zend_list_delete(mysql->active_result_id);
mysql->active_result_id = 0;
}
} while(0);
convert_to_string_ex(query); convert_to_string_ex(query);
@ -1386,6 +1413,8 @@ PHP_FUNCTION(mysql_list_dbs)
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
PHPMY_UNBUFFERED_QUERY_CHECK();
if ((mysql_result=mysql_list_dbs(&mysql->conn, NULL))==NULL) { if ((mysql_result=mysql_list_dbs(&mysql->conn, NULL))==NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
RETURN_FALSE; RETURN_FALSE;
@ -1426,9 +1455,12 @@ PHP_FUNCTION(mysql_list_tables)
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
convert_to_string_ex(db); convert_to_string_ex(db);
if (mysql_select_db(&mysql->conn, Z_STRVAL_PP(db))!=0) { if (!php_mysql_select_db(mysql, Z_STRVAL_PP(db) TSRMLS_CC)) {
RETURN_FALSE; RETURN_FALSE;
} }
PHPMY_UNBUFFERED_QUERY_CHECK();
if ((mysql_result=mysql_list_tables(&mysql->conn, NULL))==NULL) { if ((mysql_result=mysql_list_tables(&mysql->conn, NULL))==NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
RETURN_FALSE; RETURN_FALSE;
@ -1469,9 +1501,12 @@ PHP_FUNCTION(mysql_list_fields)
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
convert_to_string_ex(db); convert_to_string_ex(db);
if (mysql_select_db(&mysql->conn, Z_STRVAL_PP(db))!=0) { if (!php_mysql_select_db(mysql, Z_STRVAL_PP(db) TSRMLS_CC)) {
RETURN_FALSE; RETURN_FALSE;
} }
PHPMY_UNBUFFERED_QUERY_CHECK();
convert_to_string_ex(table); convert_to_string_ex(table);
if ((mysql_result=mysql_list_fields(&mysql->conn, Z_STRVAL_PP(table), NULL))==NULL) { if ((mysql_result=mysql_list_fields(&mysql->conn, Z_STRVAL_PP(table), NULL))==NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
@ -1501,6 +1536,8 @@ PHP_FUNCTION(mysql_list_processes)
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
PHPMY_UNBUFFERED_QUERY_CHECK();
mysql_result = mysql_list_processes(&mysql->conn); mysql_result = mysql_list_processes(&mysql->conn);
if (mysql_result == NULL) { if (mysql_result == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
@ -2379,6 +2416,9 @@ PHP_FUNCTION(mysql_ping)
} }
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
PHPMY_UNBUFFERED_QUERY_CHECK();
RETURN_BOOL(! mysql_ping(&mysql->conn)); RETURN_BOOL(! mysql_ping(&mysql->conn));
} }
/* }}} */ /* }}} */