Skip to content

Commit 9f5a771

Browse files
committed
Fix #22986: odbc_connect() may reuse persistent connection
`odbc_connect()` should not reuse persistent connections, since that prohibits multiple concurrent connections, which are occasionally desireable. We fix that by no longer looking for already cached connections when `odbc_connect()` is called, and instead creating a new connection instead. Closes phpGH-6223.
1 parent 8d9da8d commit 9f5a771

File tree

3 files changed

+14
-48
lines changed

3 files changed

+14
-48
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ PHP NEWS
99
. Fixed bug #80109 (Cannot skip arguments when extended debug is enabled).
1010
(Nikita)
1111

12+
- ODBC:
13+
. Fixed bug #22986 (odbc_connect() may reuse persistent connection). (cmb)
14+
1215
- PDO_Firebird:
1316
. Fixed bug #64937 (Firebird PDO preprocessing sql). (Simonov Denis)
1417

UPGRADING

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ PHP 8.0 UPGRADE NOTES
394394
. oci_internal_debug() and its alias ociinternaldebug() have been removed.
395395

396396
- ODBC:
397+
. odbc_connect() no longer reuses persistent connections.
397398
. The unused flags parameter of odbc_exec() has been removed.
398399

399400
- OpenSSL:

ext/odbc/php_odbc.c

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,15 +2167,7 @@ int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int
21672167
/* Persistent connections: two list-types le_pconn, le_conn and a plist
21682168
* where hashed connection info is stored together with index pointer to
21692169
* the actual link of type le_pconn in the list. Only persistent
2170-
* connections get hashed up. Normal connections use existing pconnections.
2171-
* Maybe this has to change with regard to transactions on pconnections?
2172-
* Possibly set autocommit to on on request shutdown.
2173-
*
2174-
* We do have to hash non-persistent connections, and reuse connections.
2175-
* In the case where two connects were being made, without closing the first
2176-
* connect, access violations were occurring. This is because some of the
2177-
* "globals" in this module should actually be per-connection variables. I
2178-
* simply fixed things to get them working for now. Shane
2170+
* connections get hashed up.
21792171
*/
21802172
/* {{{ odbc_do_connect */
21812173
void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
@@ -2184,8 +2176,7 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
21842176
size_t db_len, uid_len, pwd_len;
21852177
zend_long pv_opt = SQL_CUR_DEFAULT;
21862178
odbc_connection *db_conn;
2187-
char *hashed_details;
2188-
int hashed_len, cur_opt;
2179+
int cur_opt;
21892180

21902181
/* Now an optional 4th parameter specifying the cursor type
21912182
* defaulting to the cursors default
@@ -2212,20 +2203,15 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
22122203
persistent = 0;
22132204
}
22142205

2215-
hashed_len = spprintf(&hashed_details, 0, "%s_%s_%s_%s_%d", ODBC_TYPE, db, uid, pwd, cur_opt);
2216-
2217-
/* FIXME the idea of checking to see if our connection is already persistent
2218-
is good, but it adds a lot of overhead to non-persistent connections. We
2219-
should look and see if we can fix that somehow */
2220-
/* try to find if we already have this link in our persistent list,
2221-
* no matter if it is to be persistent or not
2222-
*/
2223-
22242206
try_and_get_another_connection:
22252207

22262208
if (persistent) {
2209+
char *hashed_details;
2210+
int hashed_len;
22272211
zend_resource *le;
22282212

2213+
hashed_len = spprintf(&hashed_details, 0, "%s_%s_%s_%s_%d", ODBC_TYPE, db, uid, pwd, cur_opt);
2214+
22292215
/* the link is not in the persistent list */
22302216
if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashed_details, hashed_len)) == NULL) {
22312217
if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {
@@ -2254,9 +2240,8 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
22542240
db_conn->res = zend_register_resource(db_conn, le_pconn);
22552241
RETVAL_RES(db_conn->res);
22562242
} else { /* found connection */
2257-
if (le->type != le_pconn) {
2258-
RETURN_FALSE;
2259-
}
2243+
ZEND_ASSERT(le->type == le_pconn);
2244+
22602245
/*
22612246
* check to see if the connection is still valid
22622247
*/
@@ -2287,50 +2272,27 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
22872272
}
22882273
}
22892274
}
2275+
efree(hashed_details);
22902276
db_conn->res = zend_register_resource(db_conn, le_pconn);
22912277
RETVAL_RES(db_conn->res);
22922278
} else { /* non persistent */
2293-
zend_resource *index_ptr, new_index_ptr;
2294-
2295-
if ((index_ptr = zend_hash_str_find_ptr(&EG(regular_list), hashed_details, hashed_len)) != NULL) {
2296-
zend_ulong conn_id;
2297-
zend_resource *p;
2279+
zend_resource new_index_ptr;
22982280

2299-
if (index_ptr->type != le_index_ptr) {
2300-
RETURN_FALSE;
2301-
}
2302-
conn_id = (zend_ulong)index_ptr->ptr;
2303-
p = zend_hash_index_find_ptr(&EG(regular_list), conn_id); /* check if the connection is still there */
2304-
2305-
if (p && p->ptr && (p->type == le_conn || p->type == le_pconn)) {
2306-
GC_ADDREF(p);
2307-
RETVAL_RES(p);
2308-
efree(hashed_details);
2309-
return;
2310-
} else {
2311-
zend_hash_str_del(&EG(regular_list), hashed_details, hashed_len);
2312-
}
2313-
}
23142281
if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {
23152282
php_error_docref(NULL, E_WARNING,"Too many open connections (%ld)",ODBCG(num_links));
2316-
efree(hashed_details);
23172283
RETURN_FALSE;
23182284
}
23192285

23202286
if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 0)) {
2321-
efree(hashed_details);
23222287
RETURN_FALSE;
23232288
}
23242289
db_conn->res = zend_register_resource(db_conn, le_conn);
23252290
RETVAL_RES(db_conn->res);
23262291
new_index_ptr.ptr = (void *)(zend_uintptr_t)Z_RES_HANDLE_P(return_value);
23272292
new_index_ptr.type = le_index_ptr;
23282293

2329-
zend_hash_str_update_mem(&EG(regular_list), hashed_details, hashed_len, (void *) &new_index_ptr,
2330-
sizeof(zend_resource));
23312294
ODBCG(num_links)++;
23322295
}
2333-
efree(hashed_details);
23342296
}
23352297
/* }}} */
23362298

0 commit comments

Comments
 (0)