b74969
From 9137acc7ecdf1542fe6fda5056a0273359682735 Mon Sep 17 00:00:00 2001
b74969
From: Remi Collet <remi@php.net>
b74969
Date: Thu, 27 Feb 2014 08:45:16 +0100
b74969
Subject: [PATCH] Fixed Bug #66762 Segfault in mysqli_stmt::bind_result() when
b74969
 link closed
b74969
b74969
Each new mysqli_stmt now increase the refcount of the link object.
b74969
So the link is really destroy after all statements.
b74969
b74969
Only implemented with libmysqlclient, as mysqlnd already implement
b74969
this internally.
b74969
b74969
So, libmysqlclient and mysqlnd have the same behavior.
b74969
---
b74969
 ext/mysqli/mysqli.c             | 9 ++++++++-
b74969
 ext/mysqli/mysqli_api.c         | 8 ++++++++
b74969
 ext/mysqli/php_mysqli_structs.h | 4 ++++
b74969
 3 files changed, 20 insertions(+), 1 deletion(-)
b74969
b74969
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
b74969
index 4e4ed5b..cbeb183 100644
b74969
--- a/ext/mysqli/mysqli.c
b74969
+++ b/ext/mysqli/mysqli.c
b74969
@@ -176,8 +176,11 @@ void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC)
b74969
 	php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
b74969
 	/* Clean output bind */
b74969
 	php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
b74969
-#endif
b74969
 
b74969
+	if (stmt->link_handle) {
b74969
+	    zend_objects_store_del_ref_by_handle(stmt->link_handle TSRMLS_CC);
b74969
+	}
b74969
+#endif
b74969
 	if (stmt->query) {
b74969
 		efree(stmt->query);
b74969
 	}
b74969
@@ -1055,6 +1058,10 @@ PHP_FUNCTION(mysqli_stmt_construct)
b74969
 		efree(stmt);
b74969
 		RETURN_FALSE;
b74969
 	}
b74969
+#ifndef MYSQLI_USE_MYSQLND
b74969
+	stmt->link_handle = Z_OBJ_HANDLE(*mysql_link);
b74969
+	zend_objects_store_add_ref_by_handle(stmt->link_handle TSRMLS_CC);
b74969
+#endif
b74969
 
b74969
 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
b74969
 	mysqli_resource->ptr = (void *)stmt;
b74969
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
b74969
index 1dbff87..0b28a43 100644
b74969
--- a/ext/mysqli/mysqli_api.c
b74969
+++ b/ext/mysqli/mysqli_api.c
b74969
@@ -1840,6 +1840,10 @@ PHP_FUNCTION(mysqli_prepare)
b74969
 		efree(stmt);
b74969
 		RETURN_FALSE;
b74969
 	}
b74969
+#ifndef MYSQLI_USE_MYSQLND
b74969
+	stmt->link_handle = Z_OBJ_HANDLE(*mysql_link);
b74969
+	zend_objects_store_add_ref_by_handle(stmt->link_handle TSRMLS_CC);
b74969
+#endif
b74969
 
b74969
 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
b74969
 	mysqli_resource->ptr = (void *)stmt;
b74969
@@ -2368,6 +2372,10 @@ PHP_FUNCTION(mysqli_stmt_init)
b74969
 		efree(stmt);
b74969
 		RETURN_FALSE;
b74969
 	}
b74969
+#ifndef MYSQLI_USE_MYSQLND
b74969
+	stmt->link_handle = Z_OBJ_HANDLE(*mysql_link);
b74969
+	zend_objects_store_add_ref_by_handle(stmt->link_handle TSRMLS_CC);
b74969
+#endif
b74969
 
b74969
 	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
b74969
 	mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
b74969
diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h
b74969
index d652592..d2fb34b 100644
b74969
--- a/ext/mysqli/php_mysqli_structs.h
b74969
+++ b/ext/mysqli/php_mysqli_structs.h
b74969
@@ -116,6 +116,10 @@ typedef struct {
b74969
 	BIND_BUFFER	param;
b74969
 	BIND_BUFFER	result;
b74969
 	char		*query;
b74969
+#ifndef MYSQLI_USE_MYSQLND
b74969
+	/* used to manage refcount with libmysql (already implement in mysqlnd) */
b74969
+	zend_object_handle link_handle;
b74969
+#endif
b74969
 } MY_STMT;
b74969
 
b74969
 typedef struct {
b74969
-- 
b74969
2.1.4
b74969
b74969
From 816a5d207270556aa5a9d74cdd8629d1b06cc350 Mon Sep 17 00:00:00 2001
b74969
From: Remi Collet <remi@php.net>
b74969
Date: Thu, 27 Feb 2014 08:48:01 +0100
b74969
Subject: [PATCH] test for bug #66762
b74969
b74969
---
b74969
 ext/mysqli/tests/bug66762.phpt | 26 ++++++++++++++++++++++++++
b74969
 1 file changed, 26 insertions(+)
b74969
 create mode 100644 ext/mysqli/tests/bug66762.phpt
b74969
b74969
diff --git a/ext/mysqli/tests/bug66762.phpt b/ext/mysqli/tests/bug66762.phpt
b74969
new file mode 100644
b74969
index 0000000..2b8a92c
b74969
--- /dev/null
b74969
+++ b/ext/mysqli/tests/bug66762.phpt
b74969
@@ -0,0 +1,26 @@
b74969
+--TEST--
b74969
+Bug #66762 	mysqli@libmysql segfault in mysqli_stmt::bind_result() when link closed
b74969
+--SKIPIF--
b74969
+
b74969
+require_once('skipif.inc');
b74969
+require_once('skipifconnectfailure.inc');
b74969
+?>
b74969
+--FILE--
b74969
+
b74969
+	require_once("connect.inc");
b74969
+
b74969
+	$mysqli = new mysqli($host, $user, $passwd, $db);
b74969
+
b74969
+	$read_stmt = $mysqli->prepare("SELECT 1");
b74969
+
b74969
+	var_dump($read_stmt->bind_result($data));
b74969
+
b74969
+	unset($mysqli);
b74969
+	var_dump($read_stmt->bind_result($data));
b74969
+	
b74969
+?>
b74969
+done!
b74969
+--EXPECT--
b74969
+bool(true)
b74969
+bool(true)
b74969
+done!
b74969
\ No newline at end of file
b74969
-- 
b74969
2.1.4
b74969