From 09fbf87a6c8cedb18e6fc5b0e8acaf3f1ac9af89 Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Thu, 6 Sep 2007 10:07:42 +0000 Subject: [PATCH] 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. --- NEWS | 1 + ext/mysqli/mysqli_api.c | 1 + ext/mysqli/mysqli_nonapi.c | 27 ++++++++++++++++++++++----- ext/mysqli/tests/bug38710.phpt | 12 ++++++++---- 4 files changed, 32 insertions(+), 9 deletions(-) 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 -- 2.50.1