From: Matteo Beccati Date: Wed, 4 Nov 2009 19:32:27 +0000 (+0000) Subject: - Properly fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction). X-Git-Tag: php-5.3.2RC1~275 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fa67c860e0ef6bb2a1dd556c9c3e33ad105143bc;p=php - Properly fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction). # Removed usage of the memory address when generating prepared statemend names # as uniqueness can't be enforced. Used a statment counter instead. --- diff --git a/NEWS b/NEWS index da42349173..b88fff5171 100644 --- a/NEWS +++ b/NEWS @@ -28,7 +28,7 @@ PHP NEWS - Fixed bug #49990 (SNMP3 warning message about security level printed twice). (Jani) - Fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted - transaction). (ben dot pineau at gmail dot com, Ilia) + transaction). (ben dot pineau at gmail dot com, Ilia, Matteo) - Fixed bug #49921 (Curl post upload functions changed). (Ilia) - Fixed bug #49855 (import_request_variables() always returns NULL). (Ilia, sjoerd at php dot net) diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 7ccbe09b3e..deeddb7951 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -232,7 +232,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, if (S->cursor_name) { efree(S->cursor_name); } - spprintf(&S->cursor_name, 0, "pdo_crsr_%016lx", (unsigned long) stmt); + spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter); #if HAVE_PQPREPARE emulate = 1; #endif @@ -262,7 +262,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, return 0; } - spprintf(&S->stmt_name, 0, "pdo_stmt_%016lx", (unsigned long)stmt); + spprintf(&S->stmt_name, 0, "pdo_stmt_%08x", ++H->stmt_counter); /* that's all for now; we'll defer the actual prepare until the first execute call */ if (nsql) { diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index bf7e33448e..b5c7f42eea 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -185,7 +185,7 @@ stmt_retry: * deallocate it and retry ONCE (thies 2005.12.15) */ if (!strcmp(sqlstate, "42P05")) { - char buf[100]; /* stmt_name == "pdo_crsr_%016lx" */ + char buf[100]; /* stmt_name == "pdo_crsr_%08x" */ PGresult *res; snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name); res = PQexec(H->server, buf); diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 50b478f340..71b6909138 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -50,6 +50,7 @@ typedef struct { int emulate_prepares; int disable_native_prepares; #endif + unsigned int stmt_counter; } pdo_pgsql_db_handle; typedef struct { diff --git a/ext/pdo_pgsql/tests/bug_49985.phpt b/ext/pdo_pgsql/tests/bug_49985.phpt new file mode 100644 index 0000000000..7ada87630a --- /dev/null +++ b/ext/pdo_pgsql/tests/bug_49985.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$db->exec("CREATE TABLE test (a int PRIMARY KEY)"); + +for ($i = 0; $i < 3; $i++) { + try { + $db->beginTransaction(); + $stmt = $db->prepare("INSERT INTO test (a) VALUES (?)"); + var_dump($stmt->execute(array(1))); + $db->commit(); + } catch (Exception $e) { + echo $e->getMessage()."\n"; + $db->rollback(); + } +} + +?> +--EXPECTF-- +bool(true) +SQLSTATE[23505]: %s"test_pkey" +SQLSTATE[23505]: %s"test_pkey" +