From e355992ff96fa0aa9ea2a68209a59c05c048e751 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Mon, 23 Apr 2001 01:41:06 +0000 Subject: [PATCH] 1) Decrease the size of needlessly large buffers. For example, it resolved the stack over flow errors reported by Johann Zuschlag. 2) Support {oj syntax for 71. servers. --- src/interfaces/odbc/columninfo.c | 30 +++++++++++++++++++++++------- src/interfaces/odbc/connection.c | 14 ++++++++------ src/interfaces/odbc/convert.c | 1 + src/interfaces/odbc/execute.c | 5 +++++ src/interfaces/odbc/qresult.c | 7 ++++--- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/interfaces/odbc/columninfo.c b/src/interfaces/odbc/columninfo.c index 08992241e28..78b6b580ed5 100644 --- a/src/interfaces/odbc/columninfo.c +++ b/src/interfaces/odbc/columninfo.c @@ -57,7 +57,8 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn) Oid new_adtid; Int2 new_adtsize; Int4 new_atttypmod = -1; - char new_field_name[MAX_MESSAGE_LEN + 1]; + /* MAX_COLUMN_LEN may be sufficient but for safety */ + char new_field_name[2 * MAX_COLUMN_LEN + 1]; SocketClass *sock; ConnInfo *ci; @@ -78,7 +79,7 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn) for (lf = 0; lf < new_num_fields; lf++) { - SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN); + SOCK_get_string(sock, new_field_name, 2 * MAX_COLUMN_LEN); new_adtid = (Oid) SOCK_get_int(sock, 4); new_adtsize = (Int2) SOCK_get_int(sock, 2); @@ -116,16 +117,30 @@ CI_free_memory(ColumnInfoClass *self) for (lf = 0; lf < num_fields; lf++) { if (self->name[lf]) + { free(self->name[lf]); + self->name[lf] = NULL; + } } /* Safe to call even if null */ - free(self->name); - free(self->adtid); - free(self->adtsize); - free(self->display_size); + self->num_fields = 0; + if (self->name) + free(self->name); + self->name = NULL; + if (self->adtid) + free(self->adtid); + self->adtid = NULL; + if (self->adtsize) + free(self->adtsize); + self->adtsize = NULL; + if (self->display_size) + free(self->display_size); + self->display_size = NULL; - free(self->atttypmod); + if (self->atttypmod) + free(self->atttypmod); + self->atttypmod = NULL; } void @@ -136,6 +151,7 @@ CI_set_num_fields(ColumnInfoClass *self, int new_num_fields) self->num_fields = new_num_fields; self->name = (char **) malloc(sizeof(char *) * self->num_fields); + memset(self->name, 0, sizeof(char *) * self->num_fields); self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields); self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields); self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields); diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c index fae3e71b6f9..29e695aca12 100644 --- a/src/interfaces/odbc/connection.c +++ b/src/interfaces/odbc/connection.c @@ -913,8 +913,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) char swallow; int id; SocketClass *sock = self->sock; - static char msgbuffer[MAX_MESSAGE_LEN + 1]; - char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups + /* ERROR_MSG_LENGTH is suffcient */ + static char msgbuffer[ERROR_MSG_LENGTH + 1]; + char cmdbuffer[ERROR_MSG_LENGTH + 1]; /* QR_set_command() dups * this string so dont * need static */ @@ -986,13 +987,13 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) { case 'A': /* Asynchronous Messages are ignored */ (void) SOCK_get_int(sock, 4); /* id of notification */ - SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); /* name of the relation the message comes from */ break; case 'C': /* portal query command, no tuples * returned */ /* read in the return message from the backend */ - SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN); + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); if (SOCK_get_errcode(sock) != 0) { self->errornumber = CONNECTION_NO_RESPONSE; @@ -1146,7 +1147,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) return res; /* instead of NULL. Zoltan */ case 'P': /* get the Portal name */ - SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); break; case 'T': /* Tuple results start here */ result_in = qi ? qi->result_in : NULL; @@ -1209,7 +1210,8 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_ c, done; SocketClass *sock = self->sock; - static char msgbuffer[MAX_MESSAGE_LEN + 1]; + /* ERROR_MSG_LENGTH is sufficient */ + static char msgbuffer[ERROR_MSG_LENGTH + 1]; int i; mylog("send_function(): conn=%u, fnid=%d, result_is_int=%d, nargs=%d\n", self, fnid, result_is_int, nargs); diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index 8b41fb1c173..2bbc463b32d 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -1322,6 +1322,7 @@ convert_escape(char *value) if ((strcmp(key, "d") == 0) || (strcmp(key, "t") == 0) || + (strcmp(key, "oj") == 0) || /* {oj syntax support for 7.1 servers */ (strcmp(key, "ts") == 0)) { /* Literal; return the escape part as-is */ diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index 9777f4324c2..5a0fb17b1b4 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -300,6 +300,11 @@ SQLExecute( stmt->data_at_exec = -1; for (i = 0; i < stmt->parameters_allocated; i++) { + Int4 *pcVal = stmt->parameters[i].used; + if (pcVal && (*pcVal == SQL_DATA_AT_EXEC || *pcVal <= SQL_LEN_DATA_AT_EXEC_OFFSET)) + stmt->parameters[i].data_at_exec = TRUE; + else + stmt->parameters[i].data_at_exec = FALSE; /* Check for data at execution parameters */ if (stmt->parameters[i].data_at_exec == TRUE) { diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c index c5ec11f9805..8299b960f58 100644 --- a/src/interfaces/odbc/qresult.c +++ b/src/interfaces/odbc/qresult.c @@ -368,8 +368,9 @@ QR_next_tuple(QResultClass *self) int end_tuple = self->rowset_size + self->base; char corrected = FALSE; TupleField *the_tuples = self->backend_tuples; - static char msgbuffer[MAX_MESSAGE_LEN + 1]; - char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups + /* ERROR_MSG_LENGTH is sufficient */ + static char msgbuffer[ERROR_MSG_LENGTH + 1]; + char cmdbuffer[ERROR_MSG_LENGTH + 1]; /* QR_set_command() dups * this string so dont * need static */ char fetch[128]; @@ -528,7 +529,7 @@ QR_next_tuple(QResultClass *self) case 'C': /* End of tuple list */ - SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN); + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); QR_set_command(self, cmdbuffer); mylog("end of tuple list -- setting inUse to false: this = %u\n", self);