]> granicus.if.org Git - php/commitdiff
Bugfix 72791: fix memory leak in PDO persistent connections
authorKeyur <kgovande@etsy.com>
Tue, 9 Aug 2016 14:01:25 +0000 (14:01 +0000)
committerKeyur <kgovande@etsy.com>
Tue, 9 Aug 2016 18:16:58 +0000 (18:16 +0000)
ext/pdo/pdo_dbh.c

index 20a72a1f59202710aafdf7ce46e83b573a3fb4a8..461c65471bae638caadbf709d31c43fd79311fa1 100644 (file)
@@ -297,7 +297,7 @@ static PHP_METHOD(PDO, dbh_constructor)
                                        /* is the connection still alive ? */
                                        if (pdbh->methods->check_liveness && FAILURE == (pdbh->methods->check_liveness)(pdbh)) {
                                                /* nope... need to kill it */
-                                               /*??? memory leak */
+                                               pdbh->refcount--;
                                                zend_list_close(le);
                                                pdbh = NULL;
                                        }
@@ -310,6 +310,7 @@ static PHP_METHOD(PDO, dbh_constructor)
                                /* need a brand new pdbh */
                                pdbh = pecalloc(1, sizeof(*pdbh), 1);
 
+                               pdbh->refcount = 1;
                                pdbh->is_persistent = 1;
                                pdbh->persistent_id = pemalloc(plen + 1, 1);
                                memcpy((char *)pdbh->persistent_id, hashkey, plen+1);
@@ -322,6 +323,7 @@ static PHP_METHOD(PDO, dbh_constructor)
                        efree(dbh);
                        /* switch over to the persistent one */
                        Z_PDO_OBJECT_P(object)->inner = pdbh;
+                       pdbh->refcount++;
                        dbh = pdbh;
                }
 
@@ -1504,8 +1506,13 @@ static void dbh_free(pdo_dbh_t *dbh, zend_bool free_persistent)
                dbh->query_stmt = NULL;
        }
 
-       if (dbh->is_persistent && !free_persistent) {
-               return;
+       if (dbh->is_persistent) {
+#if ZEND_DEBUG
+               ZEND_ASSERT(free_persistent && (dbh->refcount == 1));
+#endif
+               if (!free_persistent && (--dbh->refcount)) {
+                       return;
+               }
        }
 
        if (dbh->methods) {