From 63d7df4003beddf12a88938a9c34f7680103d683 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Mon, 29 Nov 1999 23:42:03 +0000
Subject: [PATCH] Small patch which fixes the ODBC driver so it doesn't
 segfault if: You have CommLog and Debug enabled You encounter in error in any
 operation (SQLConnect/SQLExec). Previously, the extra logging didn't check
 for NULL pointers when trying to print some of the strings- the socket error
 message could frequently be NULL by design (if there was no socket error) and
 Solaris does not handle NULLS passed to things like printf ("%s\n",string);
 gracefully. This basically duplicates the functionality found in Linux where
 passing a null pointer to printf prints "(NULL)". No very elegant, but the
 logging is for debug only anyway.

Dirk Niggemann
---
 src/interfaces/odbc/connection.c | 13 ++++++++++---
 src/interfaces/odbc/statement.c  | 19 ++++++++++++-------
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index bd82f5e7ba4..0d805a413a7 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -29,6 +29,8 @@
 
 #define STMT_INCREMENT 16  /* how many statement holders to allocate at a time */
 
+#define PRN_NULLCHECK
+
 extern GLOBAL_VALUES globals;
 
 
@@ -1345,9 +1347,13 @@ static char *func = "CC_lookup_lo";
 void
 CC_log_error(char *func, char *desc, ConnectionClass *self)
 {
+#ifdef PRN_NULLCHECK
+#define nullcheck(a) (a ? a : "(NULL)")
+#endif
+
 	if (self) {
-		qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
-		mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
+		qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck (self->errormsg));
+		mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck (self->errormsg));
 		qlog("            ------------------------------------------------------------\n");
 		qlog("            henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts);
 		qlog("            sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type);
@@ -1355,12 +1361,13 @@ CC_log_error(char *func, char *desc, ConnectionClass *self)
 		qlog("            ---------------- Socket Info -------------------------------\n");
 		if (self->sock) {
 		SocketClass *sock = self->sock;
-		qlog("            socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, sock->errormsg);
+		qlog("            socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, nullcheck(sock->errormsg));
 		qlog("            buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out);
 		qlog("            buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in);
 		}
 	}
 	else
 		qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
+#undef PRN_NULLCHECK
 }
 
diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c
index 5aa540ec277..a5fc1488a62 100644
--- a/src/interfaces/odbc/statement.c
+++ b/src/interfaces/odbc/statement.c
@@ -41,6 +41,7 @@ extern GLOBAL_VALUES globals;
 #define strnicmp(s1,s2,n)	strncasecmp(s1,s2,n)
 #endif
 #endif
+#define PRN_NULLCHECK
 
 /*	Map sql commands to statement types */
 static struct {
@@ -899,28 +900,31 @@ QueryInfo qi;
 void
 SC_log_error(char *func, char *desc, StatementClass *self)
 {
+#ifdef PRN_NULLCHECK
+#define nullcheck(a) (a ? a : "(NULL)")
+#endif
 	if (self) {
-		qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
-		mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
+		qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
+		mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
 		qlog("                 ------------------------------------------------------------\n");
 		qlog("                 hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, self->result);
 		qlog("                 manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal);
 		qlog("                 bindings=%u, bindings_allocated=%d\n", self->bindings, self->bindings_allocated);
 		qlog("                 parameters=%u, parameters_allocated=%d\n", self->parameters, self->parameters_allocated);
-		qlog("                 statement_type=%d, statement='%s'\n", self->statement_type, self->statement);
-		qlog("                 stmt_with_params='%s'\n", self->stmt_with_params);
+		qlog("                 statement_type=%d, statement='%s'\n", self->statement_type, nullcheck(self->statement));
+		qlog("                 stmt_with_params='%s'\n", nullcheck(self->stmt_with_params));
 		qlog("                 data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data);
 		qlog("                 currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd);
 		qlog("                 maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->options.maxRows, self->options.rowset_size, self->options.keyset_size, self->options.cursor_type, self->options.scroll_concurrency);
-		qlog("                 cursor_name='%s'\n", self->cursor_name);
+		qlog("                 cursor_name='%s'\n", nullcheck(self->cursor_name));
 
 		qlog("                 ----------------QResult Info -------------------------------\n");
 
 		if (self->result) {
 		QResultClass *res = self->result;
 		qlog("                 fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn);
-		qlog("                 fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, res->cursor);
-		qlog("                 message='%s', command='%s', notice='%s'\n", res->message, res->command, res->notice);
+		qlog("                 fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, nullcheck(res->cursor));
+		qlog("                 message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice));
 		qlog("                 status=%d, inTuples=%d\n", res->status, res->inTuples);
 		}
 	
@@ -929,5 +933,6 @@ SC_log_error(char *func, char *desc, StatementClass *self)
 	}
 	else
 		qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
+#undef PRN_NULLCHECK
 }
 
-- 
GitLab