Skip to content

Commit dfd2a80

Browse files
NattyNarwhalcmb69
authored andcommitted
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.
1 parent 18f1587 commit dfd2a80

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ PHP NEWS
1717
. Support for building against Oracle Client libraries 10.1 and 10.2 has been
1818
dropped. Oracle Client libraries 11.2 or newer are now required.
1919

20+
- PDO_ODBC:
21+
. Fixed bug #80909 (crash with persistent connections in PDO_ODBC). (Calvin
22+
Buckley)
23+
2024
- Standard:
2125
. net_get_interfaces() also reports wireless network interfaces on Windows.
2226
(Yurun)

ext/pdo_odbc/odbc_driver.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,16 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
487487
/* Force UID and PWD to be set in the DSN */
488488
if (dbh->username && *dbh->username && !strstr(dbh->data_source, "uid")
489489
&& !strstr(dbh->data_source, "UID")) {
490-
char *dsn;
491-
spprintf(&dsn, 0, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password);
490+
/* XXX: Do we check if password is null? */
491+
size_t new_dsn_size = strlen(dbh->data_source)
492+
+ strlen(dbh->username) + strlen(dbh->password)
493+
+ strlen(";UID=;PWD=") + 1;
494+
char *dsn = pemalloc(new_dsn_size, dbh->is_persistent);
495+
if (dsn == NULL) {
496+
/* XXX: Do we inform the caller? */
497+
goto fail;
498+
}
499+
snprintf(dsn, new_dsn_size, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password);
492500
pefree((char*)dbh->data_source, dbh->is_persistent);
493501
dbh->data_source = dsn;
494502
}

0 commit comments

Comments
 (0)