From 858e2bc8ecde70b704173d28993a977410136dab Mon Sep 17 00:00:00 2001 From: shruthi gowda Date: Wed, 15 Apr 2026 08:34:18 +0000 Subject: [PATCH v5] Add missing connection validation in ECPG ECPGdeallocate_all(), ECPGprepared_statement(), ECPGget_desc(), and ecpg_freeStmtCacheEntry() could crash or misbehave when operating on NULL or invalid connections. Add proper connection validation to prevent dereferencing NULL pointers. --- src/interfaces/ecpg/ecpglib/descriptor.c | 12 ++++++++++-- src/interfaces/ecpg/ecpglib/prepare.c | 25 ++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index 39cd5130ec9..1ad5f2d88cc 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -476,6 +476,16 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) memset(&stmt, 0, sizeof stmt); stmt.lineno = lineno; + /* desperate try to guess something sensible */ + stmt.connection = ecpg_get_connection(NULL); + if (stmt.connection == NULL) + { + ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST, + ecpg_gettext("NULL")); + va_end(args); + return false; + } + /* Make sure we do NOT honor the locale for numeric input */ /* since the database gives the standard decimal point */ /* (see comments in execute.c) */ @@ -505,8 +515,6 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) setlocale(LC_NUMERIC, "C"); #endif - /* desperate try to guess something sensible */ - stmt.connection = ecpg_get_connection(NULL); ecpg_store_result(ECPGresult, index, &stmt, &data_var); #ifdef HAVE_USELOCALE diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c index 5c7c5397535..f9489044724 100644 --- a/src/interfaces/ecpg/ecpglib/prepare.c +++ b/src/interfaces/ecpg/ecpglib/prepare.c @@ -381,8 +381,12 @@ ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con) bool ECPGdeallocate_all(int lineno, int compat, const char *connection_name) { - return ecpg_deallocate_all_conn(lineno, compat, - ecpg_get_connection(connection_name)); + struct connection *con = ecpg_get_connection(connection_name); + + if (!ecpg_init(con, connection_name, lineno)) + return false; + + return ecpg_deallocate_all_conn(lineno, compat, con); } char * @@ -395,13 +399,15 @@ ecpg_prepared(const char *name, struct connection *con) } /* return the prepared statement */ -/* lineno is not used here, but kept in to not break API */ char * ECPGprepared_statement(const char *connection_name, const char *name, int lineno) { - (void) lineno; /* keep the compiler quiet */ + struct connection *con = ecpg_get_connection(connection_name); + + if (!ecpg_init(con, connection_name, lineno)) + return NULL; - return ecpg_prepared(name, ecpg_get_connection(connection_name)); + return ecpg_prepared(name, con); } /* @@ -499,9 +505,12 @@ ecpg_freeStmtCacheEntry(int lineno, int compat, con = ecpg_get_connection(entry->connection); /* free the 'prepared_statement' list entry */ - this = ecpg_find_prepared_statement(entry->stmtID, con, &prev); - if (this && !deallocate_one(lineno, compat, con, prev, this)) - return -1; + if (con) + { + this = ecpg_find_prepared_statement(entry->stmtID, con, &prev); + if (this && !deallocate_one(lineno, compat, con, prev, this)) + return -1; + } entry->stmtID[0] = '\0'; -- 2.43.0