From: Andrey Hristov Date: Thu, 6 Sep 2007 10:07:42 +0000 (+0000) Subject: Fixed leaks with multiple connects using one mysqli object. X-Git-Tag: php-5.2.5RC1~212 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09fbf87a6c8cedb18e6fc5b0e8acaf3f1ac9af89;p=php Fixed leaks with multiple connects using one mysqli object. HEAD will be fixed during the next mysqlnd merge Fixed failing test for bug38710, 5.0 version is bad, 5.1 is ok. --- diff --git a/NEWS b/NEWS index bf40e734af..6f6a28effd 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 20??, PHP 5.2.5 +- Fixed leaks with mulitple connects on one mysqli object. (Andrey) - Fixed endianness detection on MacOS when building universal binary. (Uwe Schindler, Christian Speich, Tony) - Fixed possible buffer overflows inside the fnmatch() and glob() functions diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 48a5ed4dff..fd01ba9ffa 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -458,6 +458,7 @@ PHP_FUNCTION(mysqli_close) MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); mysql_close(mysql->mysql); + mysql->mysql = NULL; php_clear_mysql(mysql); efree(mysql); MYSQLI_CLEAR_RESOURCE(&mysql_link); diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 57685d95ed..2f9ba5325b 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -33,8 +33,8 @@ Open a connection to a mysql server */ PHP_FUNCTION(mysqli_connect) { - MY_MYSQL *mysql; - MYSQLI_RESOURCE *mysqli_resource; + MY_MYSQL *mysql = NULL; + MYSQLI_RESOURCE *mysqli_resource = NULL; zval *object = getThis(); char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; @@ -67,7 +67,22 @@ PHP_FUNCTION(mysqli_connect) } } - mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL)); + if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) { + mysqli_resource = ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr; + if (mysqli_resource && mysqli_resource->ptr && + mysqli_resource->status >= MYSQLI_STATUS_INITIALIZED) + { + mysql = (MY_MYSQL*)mysqli_resource->ptr; + php_clear_mysql(mysql); + if (mysql->mysql) { + mysql_close(mysql->mysql); + mysql->mysql = NULL; + } + } + } + if (!mysql) { + mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL)); + } if (!(mysql->mysql = mysql_init(NULL))) { efree(mysql); @@ -110,8 +125,10 @@ PHP_FUNCTION(mysqli_connect) /* set our own local_infile handler */ php_set_local_infile_handler_default(mysql); - mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); - mysqli_resource->ptr = (void *)mysql; + if (!mysqli_resource) { + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)mysql; + } mysqli_resource->status = MYSQLI_STATUS_VALID; if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) { diff --git a/ext/mysqli/tests/bug38710.phpt b/ext/mysqli/tests/bug38710.phpt index 35079ae3bf..b620568688 100755 --- a/ext/mysqli/tests/bug38710.phpt +++ b/ext/mysqli/tests/bug38710.phpt @@ -1,7 +1,9 @@ --TEST-- Bug #38710 (data leakage because of nonexisting boundary checking in statements) --SKIPIF-- - + --FILE-- prepare("SELECT REPEAT('a',100000)"); $qry->execute(); $qry->bind_result($text); $qry->fetch(); -var_dump(strlen($text), md5($text)); +if ($text !== str_repeat('a', mysqli_get_server_version($db) > 50110? 100000:(mysqli_get_server_version($db)>=50000? 8193:8191))) { + var_dump(strlen($text)); +} +echo "Done"; ?> --EXPECTF-- -int(100000) -string(32) "1af6d6f2f682f76f80e606aeaaee1680" +Done