summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanley Sufficool <ssufficool@php.net>2013-05-31 23:58:16 -0700
committerStanley Sufficool <ssufficool@php.net>2013-05-31 23:58:16 -0700
commit3b54de3db008490eeae8fba2e471a41906d1eae5 (patch)
tree63ef1c0935589d613fa15dd577c626eb99213f01
parent317653e694c8cd3a3cc4c12c527af584726a66c7 (diff)
downloadphp-git-3b54de3db008490eeae8fba2e471a41906d1eae5.tar.gz
FIX BUG #60512
FreeTDS will segfault when passwords over 30 characters are used. Truncate the password and let the server return an error if the password is still invalid.
-rw-r--r--ext/pdo_dblib/dblib_driver.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index 86c12bfa75..fb0d6d3a53 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -262,17 +262,19 @@ static struct pdo_dbh_methods dblib_methods = {
static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
{
pdo_dblib_db_handle *H;
- int i, ret = 0;
+ int i, nvars, ret = 0;
struct pdo_data_src_parser vars[] = {
- { "charset", NULL, 0 },
- { "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 },
- { "host", "127.0.0.1", 0 },
- { "dbname", NULL, 0 },
- { "secure", NULL, 0 }, /* DBSETLSECURE */
- /* TODO: DBSETLVERSION ? */
+ { "charset", NULL, 0 }
+ ,{ "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 }
+ ,{ "host", "127.0.0.1", 0 }
+ ,{ "dbname", NULL, 0 }
+ ,{ "secure", NULL, 0 } /* DBSETLSECURE */
+ /* TODO: DBSETLVERSION */
};
-
- php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
+
+ nvars = sizeof(vars)/sizeof(vars[0]);
+
+ php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
H->login = dblogin();
@@ -283,10 +285,20 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
}
if (dbh->username) {
- DBSETLUSER(H->login, dbh->username);
+ if(FAIL == DBSETLUSER(H->login, dbh->username)) {
+ goto cleanup;
+ }
}
+
+ /*
+ * FreeTDS will not return FAIL but will segfault on passwords longer than 30 chars
+ */
+ if(strlen(dbh->password) > 30) dbh->password[30] = 0;
+
if (dbh->password) {
- DBSETLPWD(H->login, dbh->password);
+ if(FAIL == DBSETLPWD(H->login, dbh->password)) {
+ goto cleanup;
+ }
}
#if !PHP_DBLIB_IS_MSSQL
@@ -302,7 +314,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
H->link = dbopen(H->login, vars[2].optval);
- if (H->link == NULL) {
+ if (!H->link) {
goto cleanup;
}
@@ -324,7 +336,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
dbh->alloc_own_columns = 1;
cleanup:
- for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
+ for (i = 0; i < nvars; i++) {
if (vars[i].freeme) {
efree(vars[i].optval);
}