]> granicus.if.org Git - php/commitdiff
Fixed bug #70221 (persistent sqlite connection + custom function segfaults)
authorXinchen Hui <laruence@php.net>
Mon, 10 Aug 2015 11:00:35 +0000 (19:00 +0800)
committerXinchen Hui <laruence@php.net>
Mon, 10 Aug 2015 11:00:35 +0000 (19:00 +0800)
NEWS
ext/pdo/pdo_dbh.c
ext/pdo_sqlite/tests/bug70221.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index e8731812493fdae6a128f89b268370a02112175f..a43b2a4399af63dfd1ed99902a76c03a799d7441 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ PHP                                                                        NEWS
   . Fixed bug #66606 (Sets HTTP_CONTENT_TYPE but not CONTENT_TYPE).
     (wusuopu, cmb)
 
+- PDO:
+  . Fixed bug #70221 (persistent sqlite connection + custom function
+    segfaults). (Laruence)
+
 - Phpdbg:
   . Fixed bug #70214 (FASYNC not defined, needs sys/file.h include). (Bob)
 
index 70a8bd2ea5bcf8b80d6ea083f7f88477754368aa..ec5f33f7f738acf1522e00f4561cf1ffda43a3df 100644 (file)
@@ -1262,6 +1262,15 @@ static void cls_method_dtor(zval *el) /* {{{ */ {
 }
 /* }}} */
 
+static void cls_method_pdtor(zval *el) /* {{{ */ {
+       zend_function *func = (zend_function*)Z_PTR_P(el);
+       if (func->common.function_name) {
+               zend_string_release(func->common.function_name);
+       }
+       pefree(func, 1);
+}
+/* }}} */
+
 /* {{{ overloaded object handlers for PDO class */
 int pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind)
 {
@@ -1283,12 +1292,13 @@ int pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind)
        if (!(dbh->cls_methods[kind] = pemalloc(sizeof(HashTable), dbh->is_persistent))) {
                php_error_docref(NULL, E_ERROR, "out of memory while allocating PDO methods.");
        }
-       zend_hash_init_ex(dbh->cls_methods[kind], 8, NULL, cls_method_dtor, dbh->is_persistent, 0);
+       zend_hash_init_ex(dbh->cls_methods[kind], 8, NULL,
+                       dbh->is_persistent? cls_method_pdtor : cls_method_dtor, dbh->is_persistent, 0);
 
        while (funcs->fname) {
                ifunc->type = ZEND_INTERNAL_FUNCTION;
                ifunc->handler = funcs->handler;
-               ifunc->function_name = zend_string_init(funcs->fname, strlen(funcs->fname), 0);
+               ifunc->function_name = zend_string_init(funcs->fname, strlen(funcs->fname), dbh->is_persistent);
                ifunc->scope = dbh_obj->std.ce;
                ifunc->prototype = NULL;
                if (funcs->flags) {
diff --git a/ext/pdo_sqlite/tests/bug70221.phpt b/ext/pdo_sqlite/tests/bug70221.phpt
new file mode 100644 (file)
index 0000000..1ee2378
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Bug #70221 (persistent sqlite connection + custom function segfaults)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_sqlite')) print 'skip not loaded';
+?>
+--FILE--
+<?php
+$db = new PDO('sqlite:test.sqlite', null, null, array(PDO::ATTR_PERSISTENT => true));
+function _test() { return 42; }
+$db->sqliteCreateFunction('test', '_test', 0);
+print("Everything is fine, no exceptions here\n");
+?>
+--EXPECT--
+Everything is fine, no exceptions here