1) Decrease the size of needlessly large buffers. For example, it
authorHiroshi Inoue <inoue@tpf.co.jp>
Mon, 23 Apr 2001 01:41:06 +0000 (01:41 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Mon, 23 Apr 2001 01:41:06 +0000 (01:41 +0000)
   resolved the stack over flow errors reported by Johann Zuschlag.
2) Support {oj syntax for 71. servers.

src/interfaces/odbc/columninfo.c
src/interfaces/odbc/connection.c
src/interfaces/odbc/convert.c
src/interfaces/odbc/execute.c
src/interfaces/odbc/qresult.c

index 08992241e28622448c26c50767d1d64a8d2f4e04..78b6b580ed58f5d235c5aec8c77c230a4bf8cd22 100644 (file)
@@ -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);
-
-   free(self->atttypmod);
+   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;
+
+   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);
index fae3e71b6f96aa9140960fae54cf18789194ff27..29e695aca1262eb7365484b497ee4cec4e7ff3ed 100644 (file)
@@ -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);
index 8b41fb1c17333f4f7da1b859880b27a3ad12bda9..2bbc463b32d213ab0b7e02396851740c4d3dead4 100644 (file)
@@ -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 */
index 9777f4324c2db4a4ac4792bcff9df96c2f8c8d63..5a0fb17b1b4b802e17d209fdda4353a204da8fec 100644 (file)
@@ -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)
            {
index c5ec11f98051367e60c375cbe07d87c5d22f2b92..8299b960f58dc18b9673e2b9043921255537ec2c 100644 (file)
@@ -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);