From e3d9e18e7b24ba2d5c9e420510e804330c94f955 Mon Sep 17 00:00:00 2001
From: Xinchen Hui <laruence@php.net>
Date: Tue, 5 Nov 2013 11:04:55 +0800
Subject: [PATCH] Fixed Bug #66034 (Segmentation Fault when constructor of PDO
 statement throws an exception)

I know zend_call_function will initilize retval_ptr_ptr, but still set
it to NULL explict is more readable
---
 NEWS                               |  6 +++++-
 ext/pdo/pdo_dbh.c                  |  4 ++--
 ext/pdo_sqlite/tests/bug66033.phpt | 33 ++++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 3 deletions(-)
 create mode 100644 ext/pdo_sqlite/tests/bug66033.phpt

diff --git a/NEWS b/NEWS
index e5b79ec7bf..c3e70d94a3 100644
--- a/NEWS
+++ b/NEWS
@@ -18,10 +18,14 @@ PHP                                                                        NEWS
 - FTP:
   . Fixed bug #65667 (ftp_nb_continue produces segfault). (Philip Hofstetter)
 
-- ODBC
+- ODBC:
   . Fixed bug #65950 (Field name truncation if the field name is bigger than 
     32 characters). (patch submitted by: michael dot y at zend dot com, Yasuo)
 
+- PDO:
+  . Fixed bug #66033 (Segmentation Fault when constructor of PDO statement 
+    throws an exception). (Laruence)
+
 - Sockets:
   . Fixed bug #65808 (the socket_connect() won't work with IPv6 address).
     (Mike)
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index d5860b1a1e..ac8d29a95c 100644
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -460,7 +460,7 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry
 	if (dbstmt_ce->constructor) {
 		zend_fcall_info fci;
 		zend_fcall_info_cache fcc;
-		zval *retval;
+		zval *retval = NULL;
 
 		fci.size = sizeof(zend_fcall_info);
 		fci.function_table = &dbstmt_ce->function_table;
@@ -495,7 +495,7 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry
 			zval_dtor(object);
 			ZVAL_NULL(object);
 			object = NULL; /* marks failure */
-		} else {
+		} else if (retval) {
 			zval_ptr_dtor(&retval);
 		}
 			
diff --git a/ext/pdo_sqlite/tests/bug66033.phpt b/ext/pdo_sqlite/tests/bug66033.phpt
new file mode 100644
index 0000000000..28da3b54bf
--- /dev/null
+++ b/ext/pdo_sqlite/tests/bug66033.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #66033 (Segmentation Fault when constructor of PDO statement throws an exception)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_sqlite')) print 'skip not loaded';
+?>
+--FILE--
+<?php
+class DBStatement extends PDOStatement {
+	public $dbh;
+	protected function __construct($dbh) {
+		$this->dbh = $dbh;
+		throw new Exception("Blah");
+	}
+}
+
+$pdo = new PDO('sqlite::memory:', null, null);
+$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement',
+	array($pdo)));
+$pdo->exec("CREATE TABLE IF NOT EXISTS messages (
+	id INTEGER PRIMARY KEY,
+	title TEXT,
+	message TEXT,
+	time INTEGER)");
+
+try {
+	$pdoStatement = $pdo->query("select * from messages");
+} catch (Exception $e) {
+	var_dump($e->getMessage());
+}
+?>
+--EXPECTF--
+string(4) "Blah"
-- 
2.40.0