Fix #80909: crash with persistent connections in PDO_ODBC

When we have a complex connection string (more than a DSN), PHP
appends a UID and PWD if none are present and a username and password
are called, so SQLDriverConnect works as expected.

However, it seems spprintf doesn't allocate with persistence if
required. As a result, it'll be considering leaking and crash PHP on
free when a persistent connection is used.

Closes GH-8110.
This commit is contained in:
Calvin Buckley 2022-02-17 14:40:56 -04:00 committed by Christoph M. Becker
parent 18f158723b
commit dfd2a80b69
No known key found for this signature in database
GPG Key ID: D66C9593118BCCB6
2 changed files with 14 additions and 2 deletions

4
NEWS
View File

@ -17,6 +17,10 @@ PHP NEWS
. Support for building against Oracle Client libraries 10.1 and 10.2 has been
dropped. Oracle Client libraries 11.2 or newer are now required.
- PDO_ODBC:
. Fixed bug #80909 (crash with persistent connections in PDO_ODBC). (Calvin
Buckley)
- Standard:
. net_get_interfaces() also reports wireless network interfaces on Windows.
(Yurun)

View File

@ -487,8 +487,16 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
/* Force UID and PWD to be set in the DSN */
if (dbh->username && *dbh->username && !strstr(dbh->data_source, "uid")
&& !strstr(dbh->data_source, "UID")) {
char *dsn;
spprintf(&dsn, 0, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password);
/* XXX: Do we check if password is null? */
size_t new_dsn_size = strlen(dbh->data_source)
+ strlen(dbh->username) + strlen(dbh->password)
+ strlen(";UID=;PWD=") + 1;
char *dsn = pemalloc(new_dsn_size, dbh->is_persistent);
if (dsn == NULL) {
/* XXX: Do we inform the caller? */
goto fail;
}
snprintf(dsn, new_dsn_size, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password);
pefree((char*)dbh->data_source, dbh->is_persistent);
dbh->data_source = dsn;
}