summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2018-07-30 18:27:59 +0200
committerAnatol Belski <ab@php.net>2018-07-30 18:27:59 +0200
commitcc69950b1527b321bf54a9394938d57e8f5a35cc (patch)
tree16ef3f670d59eacbe50870316ebae51e7400503a
parented7e3bc70a89a0838a5b7e44928cbd65aec50bb1 (diff)
downloadphp-git-cc69950b1527b321bf54a9394938d57e8f5a35cc.tar.gz
Fixed bug #75402 Possible Memory Leak using PDO::CURSOR_SCROLL option
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c6
-rw-r--r--ext/pdo_pgsql/tests/bug75402.phpt113
2 files changed, 119 insertions, 0 deletions
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index b401917669..a9df2a97bf 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -165,6 +165,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt)
pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
return 0;
}
+ PQclear(S->result);
/* the cursor was declared correctly */
S->is_prepared = 1;
@@ -434,6 +435,11 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
return 0;
}
+ if(S->result) {
+ PQclear(S->result);
+ S->result = NULL;
+ }
+
spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name);
efree(ori_str);
S->result = PQexec(S->H->server, q);
diff --git a/ext/pdo_pgsql/tests/bug75402.phpt b/ext/pdo_pgsql/tests/bug75402.phpt
new file mode 100644
index 0000000000..4595ca93f2
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug75402.phpt
@@ -0,0 +1,113 @@
+--TEST--
+PDO PgSQL Bug #75402 Possible Memory Leak using PDO::CURSOR_SCROLL option
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+
+$resp = new \stdClass();
+$resp->entries = [];
+
+$db->query('DROP TABLE IF EXISTS bug75402 CASCADE');
+$db->query('CREATE TABLE bug75402 (
+ "id" character varying(64) NOT NULL,
+ "group_id" character varying(64) NOT NULL,
+ "submitter" character varying(320) NOT NULL,
+ "operation" character varying(32) NOT NULL,
+ "description" character varying(320) NOT NULL,
+ "stage" character varying(16) NOT NULL,
+ "status" character varying(64) NOT NULL,
+ "progress" integer NOT NULL,
+ "insert_datetime" timestamp(3) NOT NULL,
+ "begin_datetime" timestamp(3),
+ "end_datetime" timestamp(3),
+ "life_hours" integer NOT NULL,
+ "family" character varying(32) NOT NULL,
+ "parallelism_group" character varying(32) NOT NULL,
+ "max_parallelism" integer NOT NULL,
+ "hidden" boolean NOT NULL,
+ "abort" boolean NOT NULL,
+ "order_folder_pathname" character varying(320),
+ "worker" character varying(32) NOT NULL,
+ CONSTRAINT "pk_bug75402" PRIMARY KEY ("id")
+) WITH (oids = false);');
+
+
+
+$db->query("INSERT INTO bug75402 (\"id\", \"group_id\", \"submitter\", \"operation\", \"description\", \"stage\", \"status\", \"progress\", \"insert_datetime\", \"begin_datetime\", \"end_datetime\", \"life_hours\", \"family\", \"parallelism_group\", \"max_parallelism\", \"hidden\", \"abort\", \"order_folder_pathname\", \"worker\") VALUES
+('20171016083645_5337', 'G_20171016083645_5337', 'TESTPetunia', 'IMPORT', '', 'DON', 'Completed', 100, '2017-10-16 08:36:45', '2017-10-16 08:36:46', '2017-10-16 08:36:46', 96, 'IMPORT', '', -1, 'f', 'f', 'C:\ProgramData\TestPath\TestApp\Jobs\Jobs\\20171016083645_5337', 'MainService')");
+
+
+
+$sql = "SELECT
+ ID as \"sID\",
+ GROUP_ID as \"sGroupID\",
+ SUBMITTER as \"sOwner\",
+ OPERATION as \"sOperation\",
+ DESCRIPTION as \"sInfo\",
+ STAGE as \"sShortStatus\",
+ STATUS as \"sStatus\",
+ PROGRESS as \"sProgress\",
+ HIDDEN as \"bHidden\",
+ to_char(INSERT_DATETIME, 'IYYY.MM.DD HH24:MI:SS') as \"sDatetime\"
+ FROM bug75402
+ ORDER BY INSERT_DATETIME DESC";
+
+if ($db) {
+ $stmt = $db->prepare($sql,
+ array(
+ // With the following options memory is not being
+ // deallocated
+ \PDO::ATTR_CURSOR => \PDO::CURSOR_SCROLL
+ // With the following option memory is de-allocated
+ // \PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY
+ )
+ );
+ $stmt->execute();
+
+ while ($entry = $stmt->fetchObject()) {
+ $resp->entries [] = $entry;
+ }
+ $stmt->closeCursor();
+ $stmt = null;
+ $db = null;
+}
+
+var_dump($resp);
+
+--EXPECT--
+object(stdClass)#2 (1) {
+ ["entries"]=>
+ array(1) {
+ [0]=>
+ object(stdClass)#4 (10) {
+ ["sid"]=>
+ string(19) "20171016083645_5337"
+ ["sgroupid"]=>
+ string(21) "G_20171016083645_5337"
+ ["sowner"]=>
+ string(11) "TESTPetunia"
+ ["soperation"]=>
+ string(6) "IMPORT"
+ ["sinfo"]=>
+ string(0) ""
+ ["sshortstatus"]=>
+ string(3) "DON"
+ ["sstatus"]=>
+ string(9) "Completed"
+ ["sprogress"]=>
+ string(3) "100"
+ ["bhidden"]=>
+ bool(false)
+ ["sdatetime"]=>
+ string(19) "2017.10.16 08:36:45"
+ }
+ }
+}