[PATCHES] Check for failed memory allocations in libpq

2003-07-31 Thread Dave Allen
Attached is a patch (against 7.3.4) to check the return values of some
calls (malloc, realloc, etc.) for failed memory allocations in libpq.


-- 
Dave Allen
[EMAIL PROTECTED]
--- postgresql-7.3.4-orig/src/interfaces/libpq/fe-exec.cWed Sep  4 13:31:47 
2002
+++ postgresql-7.3.4/src/interfaces/libpq/fe-exec.c Wed Jul 30 16:04:20 2003
@@ -365,6 +365,8 @@
PGresult   *result;
 
result = (PGresult *) malloc(sizeof(PGresult));
+   if (result == NULL)
+   return NULL;
 
result-xconn = conn;   /* might be NULL */
result-ntups = 0;
@@ -966,8 +968,12 @@
if (pqGets(conn-workBuffer, conn))
return;
if (conn-result == NULL)
+   {
conn-result = 
PQmakeEmptyPGresult(conn,
   
PGRES_COMMAND_OK);
+   if (conn-result == NULL)
+   return;
+   }
strncpy(conn-result-cmdStatus, 
conn-workBuffer.data,
CMDSTATUS_LEN);
conn-asyncStatus = PGASYNC_READY;
@@ -994,8 +1000,12 @@
DONOTICE(conn, noticeWorkspace);
}
if (conn-result == NULL)
+   {
conn-result = 
PQmakeEmptyPGresult(conn,
   
   PGRES_EMPTY_QUERY);
+   if (conn-result == NULL)
+   return;
+   }
conn-asyncStatus = PGASYNC_READY;
break;
case 'K':   /* secret key data from the 
backend */
@@ -1113,6 +1123,8 @@
int i;
 
result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
+   if (result == NULL)
+   return EOF;
 
/* parseInput already read the 'T' label. */
/* the next two bytes are the number of fields  */
@@ -1128,6 +1140,11 @@
{
result-attDescs = (PGresAttDesc *)
pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
+   if (result-attDescs == NULL)
+   {
+   PQclear(result);
+   return EOF;
+   }
MemSet((char *) result-attDescs, 0, nfields * sizeof(PGresAttDesc));
}
 
@@ -1209,7 +1226,11 @@
nbytes = (nfields + BYTELEN - 1) / BYTELEN;
/* malloc() only for unusually large field counts... */
if (nbytes  sizeof(std_bitmap))
+   {
bitmap = (char *) malloc(nbytes);
+   if (bitmap == NULL)
+   goto outOfMemory;
+   }
 
if (pqGetnchar(bitmap, nbytes, conn))
goto EOFexit;
@@ -1525,6 +1546,9 @@
 */
newNotify = (PGnotify *) malloc(sizeof(PGnotify) +

strlen(conn-workBuffer.data) +1);
+   if (newNotify == NULL)
+   return EOF;
+
newNotify-relname = (char *) newNotify + sizeof(PGnotify);
strcpy(newNotify-relname, conn-workBuffer.data);
newNotify-be_pid = be_pid;

---(end of broadcast)---
TIP 3: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [PATCHES] Check for failed memory allocations in libpq

2003-07-31 Thread Tom Lane
Dave Allen [EMAIL PROTECTED] writes:
 Attached is a patch (against 7.3.4) to check the return values of some
 calls (malloc, realloc, etc.) for failed memory allocations in libpq.

You sure you aren't just trading one misbehavior for another?  The
change in PQmakeEmptyPGresult, for example, just moves the core dump
somewhere else, unless you find reasonable fallbacks for *all* its
callers (including applications you don't have the source code for,
but in any case including every one of the calls in libpq).

regards, tom lane

---(end of broadcast)---
TIP 5: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faqs/FAQ.html


Re: [PATCHES] Check for failed memory allocations in libpq

2003-07-31 Thread Dave Allen
Apologies if I missed anything, but I thought I fixed any callers of
PQmakeEmptyPQresult that weren't already checking (parseInput and
getRowDescriptions were the only ones).

I of course can't fix any applications I don't have the source for, but
if I missed something in libpq, I'd be more than happy to go back and
try to fix it.


On Thu, 2003-07-31 at 07:05, Tom Lane wrote:
 Dave Allen [EMAIL PROTECTED] writes:
  Attached is a patch (against 7.3.4) to check the return values of some
  calls (malloc, realloc, etc.) for failed memory allocations in libpq.
 
 You sure you aren't just trading one misbehavior for another?  The
 change in PQmakeEmptyPGresult, for example, just moves the core dump
 somewhere else, unless you find reasonable fallbacks for *all* its
 callers (including applications you don't have the source code for,
 but in any case including every one of the calls in libpq).
 
   regards, tom lane
 
 ---(end of broadcast)---
 TIP 5: Have you checked our extensive FAQ?
 
http://www.postgresql.org/docs/faqs/FAQ.html
-- 
Dave Allen
[EMAIL PROTECTED]


---(end of broadcast)---
TIP 7: don't forget to increase your free space map settings


Re: [PATCHES] Check for failed memory allocations in libpq

2003-07-31 Thread Tom Lane
Dave Allen [EMAIL PROTECTED] writes:
 You sure you aren't just trading one misbehavior for another?

 Apologies if I missed anything, but I thought I fixed any callers of
 PQmakeEmptyPQresult that weren't already checking (parseInput and
 getRowDescriptions were the only ones).

Well, I'm concerned about the global implications.  For instance, I
think making parseInput simply return on malloc failure *without doing
any more* will convert out-of-memory from a core dump into an infinite
loop; which is hardly an improvement.  (See PQgetResult for one example
of a place that will loop till it gets something.)

I'd be the first to admit that libpq's error handling isn't very good,
but I think fixing it will take some wholesale rework of the internal
calling conventions, not a few lines of localized patches.

Having said that, though, CVS tip does have some progress on this
matter; it will usually behave reasonably when it runs out of memory for
a query result.  If you'd like to pursue the matter, please pull down
CVS tip and see what you can do with it.  The patch as given would not
be much use to us anyway because of the changes since 7.3...

regards, tom lane

---(end of broadcast)---
TIP 8: explain analyze is your friend