Skip to content

Commit e318ab9

Browse files
authored
Fix PG_ErrorInfo and ER_ReturnError when error message is larger than 65535 bytes (#70)
1 parent 7adc6a1 commit e318ab9

File tree

3 files changed

+29
-29
lines changed

3 files changed

+29
-29
lines changed

environ.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "statement.h"
2222
#include <stdlib.h>
2323
#include <string.h>
24+
#include <stdint.h>
2425
#include "pgapifunc.h"
2526
#ifdef WIN32
2627
#include <winsock2.h>
@@ -123,32 +124,36 @@ PG_ErrorInfo *
123124
ER_Constructor(SDWORD errnumber, const char *msg)
124125
{
125126
PG_ErrorInfo *error;
126-
ssize_t aladd, errsize;
127+
size_t errsize;
128+
UInt4 aladd;
127129

128130
if (DESC_OK == errnumber)
129131
return NULL;
130132
if (msg)
131133
{
132134
errsize = strlen(msg);
133-
aladd = errsize - sizeof(error->__error_message) + 1;
134-
if (aladd < 0)
135+
if (errsize > UINT32_MAX)
136+
errsize = UINT32_MAX;
137+
138+
if (errsize > sizeof(error->__error_message) - 1)
139+
aladd = errsize - (sizeof(error->__error_message) - 1);
140+
else
135141
aladd = 0;
136142
}
137143
else
138144
{
139-
errsize = -1;
145+
errsize = 0;
140146
aladd = 0;
141147
}
142148
error = (PG_ErrorInfo *) malloc(sizeof(PG_ErrorInfo) + aladd);
143149
if (error)
144150
{
145151
memset(error, 0, sizeof(PG_ErrorInfo));
146152
error->status = errnumber;
147-
error->errorsize = (Int2) errsize;
153+
error->errsize = errsize;
148154
if (errsize > 0)
149155
memcpy(error->__error_message, msg, errsize);
150156
error->__error_message[errsize] = '\0';
151-
error->recsize = -1;
152157
}
153158
return error;
154159
}
@@ -163,13 +168,13 @@ PG_ErrorInfo *
163168
ER_Dup(const PG_ErrorInfo *self)
164169
{
165170
PG_ErrorInfo *new;
166-
Int4 alsize;
171+
UInt4 alsize;
167172

168173
if (!self)
169174
return NULL;
170175
alsize = sizeof(PG_ErrorInfo);
171-
if (self->errorsize > 0)
172-
alsize += self->errorsize;
176+
if (self->errsize > sizeof(self->__error_message) - 1)
177+
alsize += self->errsize - (sizeof(self->__error_message) - 1);
173178
new = (PG_ErrorInfo *) malloc(alsize);
174179
if (new)
175180
memcpy(new, self, alsize);
@@ -193,21 +198,20 @@ ER_ReturnError(PG_ErrorInfo *pgerror,
193198
PG_ErrorInfo *error;
194199
BOOL partial_ok = ((flag & PODBC_ALLOW_PARTIAL_EXTRACT) != 0);
195200
const char *msg;
196-
UWORD msglen, wrtlen, pcblen;
197-
UInt4 stapos;
201+
UInt4 stapos, msglen, wrtlen, pcblen;
198202

199203
if (!pgerror)
200204
return SQL_NO_DATA_FOUND;
201205
error = pgerror;
202206
msg = error->__error_message;
203207
MYLOG(0, "entering status = %d, msg = #%s#\n", error->status, msg);
204-
msglen = (SQLSMALLINT) strlen(msg);
208+
msglen = error->errsize;
205209
/*
206210
* Even though an application specifies a larger error message
207211
* buffer, the driver manager changes it silently.
208212
* Therefore we divide the error message into ...
209213
*/
210-
if (error->recsize < 0)
214+
if (error->recsize == 0)
211215
{
212216
if (cbErrorMsgMax > 0)
213217
error->recsize = cbErrorMsgMax - 1; /* apply the first request */
@@ -216,15 +220,12 @@ ER_ReturnError(PG_ErrorInfo *pgerror,
216220
}
217221
else if (1 == RecNumber && cbErrorMsgMax > 0)
218222
error->recsize = cbErrorMsgMax - 1;
219-
if (RecNumber < 0)
220-
{
221-
if (0 == error->errorpos)
222-
RecNumber = 1;
223-
else
224-
RecNumber = 2 + (error->errorpos - 1) / error->recsize;
225-
}
226-
stapos = (RecNumber - 1) * error->recsize;
227-
if (stapos > msglen)
223+
if (RecNumber > 0)
224+
stapos = (RecNumber - 1) * error->recsize;
225+
else
226+
stapos = error->errpos;
227+
228+
if (stapos >= msglen)
228229
return SQL_NO_DATA_FOUND;
229230
pcblen = wrtlen = msglen - stapos;
230231
if (pcblen > error->recsize)
@@ -257,6 +258,7 @@ ER_ReturnError(PG_ErrorInfo *pgerror,
257258
if (NULL != szSqlState)
258259
strncpy_null((char *) szSqlState, error->sqlstate, 6);
259260

261+
error->errpos = stapos + wrtlen;
260262
MYLOG(0, " szSqlState = '%s',len=%d, szError='%s'\n", szSqlState, pcblen, szErrorMsg);
261263
if (wrtlen < pcblen)
262264
return SQL_SUCCESS_WITH_INFO;

psqlodbc.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -614,12 +614,11 @@ typedef struct QueryInfo_
614614
typedef struct
615615
{
616616
UInt4 status;
617-
Int2 errorsize;
618-
Int2 recsize;
619-
Int2 errorpos;
617+
UInt4 errsize;
618+
UInt4 errpos;
619+
UInt2 recsize;
620620
char sqlstate[6];
621-
SQLLEN diag_row_count;
622-
char __error_message[40];
621+
char __error_message[44];
623622
} PG_ErrorInfo;
624623
PG_ErrorInfo *ER_Constructor(SDWORD errornumber, const char *errormsg);
625624
PG_ErrorInfo *ER_Dup(const PG_ErrorInfo *from);

statement.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,9 +1409,8 @@ SC_create_errorinfo(const StatementClass *self, PG_ErrorInfo *pgerror_fail_safe)
14091409
memset(pgerror_fail_safe, 0, sizeof(*pgerror_fail_safe));
14101410
pgerror = pgerror_fail_safe;
14111411
pgerror->status = self->__error_number;
1412-
pgerror->errorsize = sizeof(pgerror->__error_message);
14131412
STRCPY_FIXED(pgerror->__error_message, ermsg);
1414-
pgerror->recsize = -1;
1413+
pgerror->errsize = strlen(pgerror->__error_message);
14151414
}
14161415
else
14171416
return NULL;

0 commit comments

Comments
 (0)