Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e355992

Browse files
author
Hiroshi Inoue
committed
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.
1 parent cc6bdb3 commit e355992

File tree

5 files changed

+42
-17
lines changed

5 files changed

+42
-17
lines changed

src/interfaces/odbc/columninfo.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
5757
Oid new_adtid;
5858
Int2 new_adtsize;
5959
Int4 new_atttypmod = -1;
60-
char new_field_name[MAX_MESSAGE_LEN + 1];
60+
/* MAX_COLUMN_LEN may be sufficient but for safety */
61+
char new_field_name[2 * MAX_COLUMN_LEN + 1];
6162
SocketClass *sock;
6263
ConnInfo *ci;
6364

@@ -78,7 +79,7 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
7879
for (lf = 0; lf < new_num_fields; lf++)
7980
{
8081

81-
SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN);
82+
SOCK_get_string(sock, new_field_name, 2 * MAX_COLUMN_LEN);
8283
new_adtid = (Oid) SOCK_get_int(sock, 4);
8384
new_adtsize = (Int2) SOCK_get_int(sock, 2);
8485

@@ -116,16 +117,30 @@ CI_free_memory(ColumnInfoClass *self)
116117
for (lf = 0; lf < num_fields; lf++)
117118
{
118119
if (self->name[lf])
120+
{
119121
free(self->name[lf]);
122+
self->name[lf] = NULL;
123+
}
120124
}
121125

122126
/* Safe to call even if null */
123-
free(self->name);
124-
free(self->adtid);
125-
free(self->adtsize);
126-
free(self->display_size);
127-
128-
free(self->atttypmod);
127+
self->num_fields = 0;
128+
if (self->name)
129+
free(self->name);
130+
self->name = NULL;
131+
if (self->adtid)
132+
free(self->adtid);
133+
self->adtid = NULL;
134+
if (self->adtsize)
135+
free(self->adtsize);
136+
self->adtsize = NULL;
137+
if (self->display_size)
138+
free(self->display_size);
139+
self->display_size = NULL;
140+
141+
if (self->atttypmod)
142+
free(self->atttypmod);
143+
self->atttypmod = NULL;
129144
}
130145

131146
void
@@ -136,6 +151,7 @@ CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
136151
self->num_fields = new_num_fields;
137152

138153
self->name = (char **) malloc(sizeof(char *) * self->num_fields);
154+
memset(self->name, 0, sizeof(char *) * self->num_fields);
139155
self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields);
140156
self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
141157
self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);

src/interfaces/odbc/connection.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -913,8 +913,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
913913
char swallow;
914914
int id;
915915
SocketClass *sock = self->sock;
916-
static char msgbuffer[MAX_MESSAGE_LEN + 1];
917-
char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups
916+
/* ERROR_MSG_LENGTH is suffcient */
917+
static char msgbuffer[ERROR_MSG_LENGTH + 1];
918+
char cmdbuffer[ERROR_MSG_LENGTH + 1]; /* QR_set_command() dups
918919
* this string so dont
919920
* need static */
920921

@@ -986,13 +987,13 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
986987
{
987988
case 'A': /* Asynchronous Messages are ignored */
988989
(void) SOCK_get_int(sock, 4); /* id of notification */
989-
SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN);
990+
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
990991
/* name of the relation the message comes from */
991992
break;
992993
case 'C': /* portal query command, no tuples
993994
* returned */
994995
/* read in the return message from the backend */
995-
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
996+
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
996997
if (SOCK_get_errcode(sock) != 0)
997998
{
998999
self->errornumber = CONNECTION_NO_RESPONSE;
@@ -1146,7 +1147,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
11461147
return res; /* instead of NULL. Zoltan */
11471148

11481149
case 'P': /* get the Portal name */
1149-
SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN);
1150+
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
11501151
break;
11511152
case 'T': /* Tuple results start here */
11521153
result_in = qi ? qi->result_in : NULL;
@@ -1209,7 +1210,8 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
12091210
c,
12101211
done;
12111212
SocketClass *sock = self->sock;
1212-
static char msgbuffer[MAX_MESSAGE_LEN + 1];
1213+
/* ERROR_MSG_LENGTH is sufficient */
1214+
static char msgbuffer[ERROR_MSG_LENGTH + 1];
12131215
int i;
12141216

12151217
mylog("send_function(): conn=%u, fnid=%d, result_is_int=%d, nargs=%d\n", self, fnid, result_is_int, nargs);

src/interfaces/odbc/convert.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,7 @@ convert_escape(char *value)
13221322

13231323
if ((strcmp(key, "d") == 0) ||
13241324
(strcmp(key, "t") == 0) ||
1325+
(strcmp(key, "oj") == 0) || /* {oj syntax support for 7.1 servers */
13251326
(strcmp(key, "ts") == 0))
13261327
{
13271328
/* Literal; return the escape part as-is */

src/interfaces/odbc/execute.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ SQLExecute(
300300
stmt->data_at_exec = -1;
301301
for (i = 0; i < stmt->parameters_allocated; i++)
302302
{
303+
Int4 *pcVal = stmt->parameters[i].used;
304+
if (pcVal && (*pcVal == SQL_DATA_AT_EXEC || *pcVal <= SQL_LEN_DATA_AT_EXEC_OFFSET))
305+
stmt->parameters[i].data_at_exec = TRUE;
306+
else
307+
stmt->parameters[i].data_at_exec = FALSE;
303308
/* Check for data at execution parameters */
304309
if (stmt->parameters[i].data_at_exec == TRUE)
305310
{

src/interfaces/odbc/qresult.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,9 @@ QR_next_tuple(QResultClass *self)
368368
int end_tuple = self->rowset_size + self->base;
369369
char corrected = FALSE;
370370
TupleField *the_tuples = self->backend_tuples;
371-
static char msgbuffer[MAX_MESSAGE_LEN + 1];
372-
char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups
371+
/* ERROR_MSG_LENGTH is sufficient */
372+
static char msgbuffer[ERROR_MSG_LENGTH + 1];
373+
char cmdbuffer[ERROR_MSG_LENGTH + 1]; /* QR_set_command() dups
373374
* this string so dont
374375
* need static */
375376
char fetch[128];
@@ -528,7 +529,7 @@ QR_next_tuple(QResultClass *self)
528529

529530

530531
case 'C': /* End of tuple list */
531-
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
532+
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
532533
QR_set_command(self, cmdbuffer);
533534

534535
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);

0 commit comments

Comments
 (0)