aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-protocol2.c
diff options
context:
space:
mode:
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;
}
/*