Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Bug #62479 Fix bug where spaces in passwords would fail #199

Closed
wants to merge 3 commits into from

6 participants

@willfitch

Change-Id: I53679937d69b0a8897961900ebf33d197b8ce018

@willfitch willfitch Bug #62479 Fix bug where spaces in passwords would fail
Change-Id: I53679937d69b0a8897961900ebf33d197b8ce018
809c3cc
@lstrojny

Thanks! We need a test for that.

@willfitch

Test added @lstrojny

@dsp
Owner

Maybe @iliaal want to have a look,he is the official maintainer.

@iliaal

I think the patch inside http://ilia.ws/patch/pdo.txt maybe better, as it also accounts for the possibility of the password containing \ character.

@lstrojny

@iliaal will you merge your patch and close this PR?

@smalyshev
Owner

@willfitch any news?

@php-pulls
Collaborator

Comment on behalf of stas at php.net:

Looks like this one is abandoned. Since Ilia thinks different patch is better, closing this one.

@php-pulls php-pulls closed this
@willfitch

Where did this go? Just trying to see if @iliaal's patch made it in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 20, 2012
  1. @willfitch

    Bug #62479 Fix bug where spaces in passwords would fail

    willfitch authored
    Change-Id: I53679937d69b0a8897961900ebf33d197b8ce018
Commits on Sep 28, 2012
  1. @willfitch
  2. @willfitch
This page is out of date. Refresh to see the latest.
Showing with 104 additions and 4 deletions.
  1. +48 −4 ext/pdo_pgsql/pgsql_driver.c
  2. +56 −0 ext/pdo_pgsql/tests/bug62479.phpt
View
52 ext/pdo_pgsql/pgsql_driver.c
@@ -1037,8 +1037,8 @@ static struct pdo_dbh_methods pgsql_methods = {
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
{
pdo_pgsql_db_handle *H;
- int ret = 0;
- char *conn_str, *p, *e;
+ int ret = 0, password_len = 0;
+ char *conn_str, *p, *e, *tmp_pass = NULL;
long connect_timeout = 30;
H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent);
@@ -1056,23 +1056,67 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
*p = ' ';
}
+ /* If the password is defined, we need to account for special chars */
+ if (dbh->password) {
+ password_len = strlen(dbh->password);
+
+ /* If the password isn't already quoted, let's quote it */
+ if (dbh->password[0] != '\'' && dbh->password[password_len - 1] != '\'') {
+ char *source, *target, *end;
+ int new_password_length = 0;
+ tmp_pass = (char *) safe_emalloc(2, password_len, 1);
+ source = dbh->password;
+ end = source + password_len;
+ target = tmp_pass;
+ *target++ = '\'';
+
+ while (source < end) {
+ switch (*source) {
+ case '\'':
+ *target++ = '\\';
+ default:
+ *target++ = *source;
+ break;
+ }
+
+ source++;
+ }
+
+ *target++ = '\'';
+ *target++ = 0;
+ new_password_length = target - tmp_pass;
+ tmp_pass = (char *) erealloc(tmp_pass, new_password_length);
+ } else {
+ /* Our default is to just use what password has been provided -
+ * assuming it is already surrounded by quotes. This keeps BC for
+ * users who already use workarounds
+ */
+ tmp_pass = estrdup(dbh->password);
+ }
+ }
+
if (driver_options) {
connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
}
/* 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);
+ /* Free the tmp password created above */
+ if (dbh->password) {
+ efree(tmp_pass);
+ }
+
efree(conn_str);
if (PQstatus(H->server) != CONNECTION_OK) {
View
56 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($config['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, 5);
+$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($config['ENV']['PDOTEST_DSN'], $user, "my password");
+$result = $testConn->query($testQuery);
+var_dump($result->fetch()[0]);
+
+// 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($config['ENV']['PDOTEST_DSN'], $user, "my pass'word");
+$result = $testConn->query($testQuery);
+var_dump($result->fetch()[0]);
+
+// Remove the user
+$pdo->query($dropUser);
+
+?>
+--EXPECTF--
+int(1)
+int(1)
+
Something went wrong with that request. Please try again.