summaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-protocol2.c
diff options
context:
space:
mode:
authorNeil Conway <neilc@samurai.com>2005-06-12 00:00:21 +0000
committerNeil Conway <neilc@samurai.com>2005-06-12 00:00:21 +0000
commit72a5db15d190121e63126055824f38dd062428be (patch)
tree82e9ec66aca79f9e213da819b3231664a6363b63 /src/interfaces/libpq/fe-protocol2.c
parent2f1210629cf357fd0b6035e47ef10f240c82f6d5 (diff)
libpq was not consistently checking for memory allocation failures. This
patch adds missing checks to the call sites of malloc(), strdup(), PQmakeEmptyPGresult(), pqResultAlloc(), and pqResultStrdup(), and updates the documentation. Per original report from Volkan Yazici about PQmakeEmptyPGresult() not checking for malloc() failure.
Diffstat (limited to 'src/interfaces/libpq/fe-protocol2.c')
-rw-r--r--src/interfaces/libpq/fe-protocol2.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index 2501ef4a603..b5753dba445 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.17 2005/05/11 01:26:02 neilc Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.18 2005/06/12 00:00:21 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@@ -438,8 +438,12 @@ pqParseInput2(PGconn *conn)
if (pqGets(&conn->workBuffer, conn))
return;
if (conn->result == NULL)
+ {
conn->result = PQmakeEmptyPGresult(conn,
PGRES_COMMAND_OK);
+ if (!conn->result)
+ return;
+ }
strncpy(conn->result->cmdStatus, conn->workBuffer.data,
CMDSTATUS_LEN);
checkXactStatus(conn, conn->workBuffer.data);
@@ -572,19 +576,18 @@ pqParseInput2(PGconn *conn)
static int
getRowDescriptions(PGconn *conn)
{
- PGresult *result;
+ PGresult *result = NULL;
int nfields;
int i;
result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
+ if (!result)
+ goto failure;
/* parseInput already read the 'T' label. */
/* the next two bytes are the number of fields */
if (pqGetInt(&(result->numAttributes), 2, conn))
- {
- PQclear(result);
- return EOF;
- }
+ goto failure;
nfields = result->numAttributes;
/* allocate space for the attribute descriptors */
@@ -592,6 +595,8 @@ getRowDescriptions(PGconn *conn)
{
result->attDescs = (PGresAttDesc *)
pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
+ if (!result->attDescs)
+ goto failure;
MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
}
@@ -606,10 +611,7 @@ getRowDescriptions(PGconn *conn)
pqGetInt(&typid, 4, conn) ||
pqGetInt(&typlen, 2, conn) ||
pqGetInt(&atttypmod, 4, conn))
- {
- PQclear(result);
- return EOF;
- }
+ goto failure;
/*
* Since pqGetInt treats 2-byte integers as unsigned, we need to
@@ -619,6 +621,8 @@ getRowDescriptions(PGconn *conn)
result->attDescs[i].name = pqResultStrdup(result,
conn->workBuffer.data);
+ if (!result->attDescs[i].name)
+ goto failure;
result->attDescs[i].tableid = 0;
result->attDescs[i].columnid = 0;
result->attDescs[i].format = 0;
@@ -630,6 +634,11 @@ getRowDescriptions(PGconn *conn)
/* Success! */
conn->result = result;
return 0;
+
+failure:
+ if (result)
+ PQclear(result);
+ return EOF;
}
/*
@@ -685,7 +694,11 @@ getAnotherTuple(PGconn *conn, bool binary)
nbytes = (nfields + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
/* malloc() only for unusually large field counts... */
if (nbytes > sizeof(std_bitmap))
+ {
bitmap = (char *) malloc(nbytes);
+ if (!bitmap)
+ goto outOfMemory;
+ }
if (pqGetnchar(bitmap, nbytes, conn))
goto EOFexit;
@@ -758,13 +771,18 @@ outOfMemory:
pqClearAsyncResult(conn);
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("out of memory for query result\n"));
+
+ /*
+ * XXX: if PQmakeEmptyPGresult() fails, there's probably not much
+ * we can do to recover...
+ */
conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
conn->asyncStatus = PGASYNC_READY;
/* Discard the failed message --- good idea? */
conn->inStart = conn->inEnd;
EOFexit:
- if (bitmap != std_bitmap)
+ if (bitmap != NULL && bitmap != std_bitmap)
free(bitmap);
return EOF;
}
@@ -780,7 +798,7 @@ EOFexit:
static int
pqGetErrorNotice2(PGconn *conn, bool isError)
{
- PGresult *res;
+ PGresult *res = NULL;
PQExpBufferData workBuf;
char *startp;
char *splitp;
@@ -792,10 +810,7 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
*/
initPQExpBuffer(&workBuf);
if (pqGets(&workBuf, conn))
- {
- termPQExpBuffer(&workBuf);
- return EOF;
- }
+ goto failure;
/*
* Make a PGresult to hold the message. We temporarily lie about the
@@ -803,8 +818,12 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
* conn->errorMessage.
*/
res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
+ if (!res)
+ goto failure;
res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
res->errMsg = pqResultStrdup(res, workBuf.data);
+ if (!res->errMsg)
+ goto failure;
/*
* Break the message into fields. We can't do very much here, but we
@@ -869,6 +888,12 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
termPQExpBuffer(&workBuf);
return 0;
+
+failure:
+ if (res)
+ PQclear(res);
+ termPQExpBuffer(&workBuf);
+ return EOF;
}
/*