com php-src: Fix #62479: Some chars not parsed in passwords: NEWS ext/pdo_pgsql/pgsql_driver.c ext/pdo_pgsql/tests/bug 62479.phpt
| From: | Will Fitch | Date: | Sun, 19 Jan 2014 00:27:00 +0000 |
| Subject: | com php-src: Fix #62479: Some chars not parsed in passwords: NEWS ext/pdo_pgsql/pgsql_driver.c ext/pdo_pgsql/tests/bug 62479.phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-75694@lists.php.net to get a copy of this message | ||
Commit: e6bb90c66a5306f3db7ca38206b27685177a65cc
Author: Will Fitch <willfitch@php.net> Sat, 18 Jan 2014 19:24:22 -0500
Parents: 3eb2b1ac4008acd13f51244c7ba009fa381e79f7
Branches: PHP-5.3
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e6bb90c66a5306f3db7ca38206b27685177a65cc
Log:
Fix #62479: Some chars not parsed in passwords
This fixes an issue where backslashes and spaces aren't
correctly parsed for passwords.
Bugs:
https://bugs.php.net/62479
Changed paths:
M NEWS
M ext/pdo_pgsql/pgsql_driver.c
A ext/pdo_pgsql/tests/bug62479.phpt
Diff:
diff --git a/NEWS b/NEWS
index 72c0939..e05c987 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 201?, PHP 5.3.29
+- PDO_pgsql:
+ . Fixed bug #62479 (PDO-psql cannot connect if password contains spaces)
+
12 Dec 2013, PHP 5.3.28
- Openssl:
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index 55f4418..e2ad143 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -1029,6 +1029,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options
TSRMLS_
pdo_pgsql_db_handle *H;
int ret = 0;
char *conn_str, *p, *e;
+ char *tmp_pass;
long connect_timeout = 30;
H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent);
@@ -1050,18 +1051,44 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options
TSRMLS_
connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
}
+ if (dbh->password) {
+ if (dbh->password[0] != '\'' &&
dbh->password[strlen(dbh->password) - 1] != '\'') {
+ char *pwd = dbh->password;
+ int pos = 1;
+
+ tmp_pass = safe_emalloc(2, strlen(dbh->password), 3);
+ tmp_pass[0] = '\'';
+
+ while (*pwd != '\0') {
+ if (*pwd == '\\' || *pwd == '\'') {
+ tmp_pass[pos++] = '\\';
+ }
+
+ tmp_pass[pos++] = *pwd++;
+ }
+
+ tmp_pass[pos++] = '\'';
+ tmp_pass[pos] = '\0';
+ } else {
+ tmp_pass = dbh->password;
+ }
+ }
+
/* support both full connection string & connection string + login and/or password */
if (dbh->username && dbh->password) {
- spprintf(&conn_str, 0, "%s user=%s password=%s connect_timeout=%ld",
dbh->data_source, dbh->username, dbh->password, connect_timeout);
+ spprintf(&conn_str, 0, "%s user=%s password=%s connect_timeout=%ld",
dbh->data_source, dbh->username, tmp_pass, connect_timeout);
} else if (dbh->username) {
spprintf(&conn_str, 0, "%s user=%s connect_timeout=%ld", dbh->data_source,
dbh->username, connect_timeout);
} else if (dbh->password) {
- spprintf(&conn_str, 0, "%s password=%s connect_timeout=%ld", dbh->data_source,
dbh->password, connect_timeout);
+ spprintf(&conn_str, 0, "%s password=%s connect_timeout=%ld", dbh->data_source,
tmp_pass, connect_timeout);
} else {
spprintf(&conn_str, 0, "%s connect_timeout=%ld", (char *) dbh->data_source,
connect_timeout);
}
H->server = PQconnectdb(conn_str);
+ if (dbh->password && tmp_pass != dbh->password) {
+ efree(tmp_pass);
+ }
efree(conn_str);
diff --git a/ext/pdo_pgsql/tests/bug62479.phpt b/ext/pdo_pgsql/tests/bug62479.phpt
new file mode 100644
index 0000000..2e19f15
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug62479.phpt
@@ -0,0 +1,56 @@
+--TEST--
+PDO PgSQL Bug #62479 (PDO-psql cannot connect if password contains spaces)
+--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();
+if (!isset($conf['ENV']['PDOTEST_DSN'])) die('no dsn found in env');
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$rand = rand(5, 5);
+
+// Assume that if we can't create a user, this test needs to be skipped
+$testQuery = "CREATE USER pdo_$rand WITH PASSWORD 'testpass'";
+$db->query($testQuery);
+$testQuery = "DROP USER pdo_$rand";
+$db->query($testQuery);
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+$rand = rand(5, 400);
+$user = "pdo_$rand";
+$template = "CREATE USER $user WITH PASSWORD '%s'";
+$dropUser = "DROP USER $user";
+$testQuery = 'SELECT 1 as verification';
+
+// Create temp user with space in password
+$sql = sprintf($template, 'my password');
+$pdo->query($sql);
+$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my password");
+$result = $testConn->query($testQuery)->fetch();
+$check = $result[0];
+var_dump($check);
+
+// Remove the user
+$pdo->query($dropUser);
+
+// Create a user with a space and single quote
+$sql = sprintf($template, "my pass''word");
+$pdo->query($sql);
+
+$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my pass'word");
+$result = $testConn->query($testQuery)->fetch();
+$check = $result[0];
+var_dump($check);
+
+// Remove the user
+$pdo->query($dropUser);
+?>
+--EXPECT--
+int(1)
+int(1)
+