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