Commit 9a5529f4 authored by Marc G. Fournier's avatar Marc G. Fournier

From: Igor <igor@sba.miami.edu>

Subject: [PATCHES] memory leak patches in libpq and psql

A couple of small memory leak patches (detected with Purify) primarily
in libpq.

* Fixed (NULL) border problem in psql (run psql, do \m, then select
  something from a table...row separators will be nulls)
* Fixed memory leak with the abovementioned border not being freed
  properly.
* Fixed memory leak in freePGconn() not freeing conn->port
* Fixed up PQclear() to free parts of PGresult only if these
  parts are not null.
* Fixed a decent memory leak that occured after executing every command
  in psql. PGresult *results was not freed most of the time.

There is still a leak being detected (2 bytes) in readline functions, but
I think this is old readline library. I will install new one and test it.
parent d9557276
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.66 1997/05/24 14:38:05 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.67 1997/06/01 15:38:42 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -612,6 +612,7 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query, ...@@ -612,6 +612,7 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
notify->relname, notify->be_pid); notify->relname, notify->be_pid);
free(notify); free(notify);
} }
PQclear(results);
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.35 1997/05/20 03:38:49 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.36 1997/06/01 15:38:52 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -588,6 +588,7 @@ freePGconn(PGconn *conn) ...@@ -588,6 +588,7 @@ freePGconn(PGconn *conn)
if (conn->dbName) free(conn->dbName); if (conn->dbName) free(conn->dbName);
if (conn->pguser) free(conn->pguser); if (conn->pguser) free(conn->pguser);
if (conn->notifyList) DLFreeList(conn->notifyList); if (conn->notifyList) DLFreeList(conn->notifyList);
if (conn->port) free(conn->port);
free(conn); free(conn);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.31 1997/06/01 04:59:25 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.32 1997/06/01 15:39:08 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -58,6 +58,9 @@ static void addTuple(PGresult *res, PGresAttValue *tup); ...@@ -58,6 +58,9 @@ static void addTuple(PGresult *res, PGresAttValue *tup);
static PGresAttValue* getTuple(PGconn *conn, PGresult *res, int binary); static PGresAttValue* getTuple(PGconn *conn, PGresult *res, int binary);
static PGresult* makeEmptyPGresult(PGconn *conn, ExecStatusType status); static PGresult* makeEmptyPGresult(PGconn *conn, ExecStatusType status);
static void fill(int length, int max, char filler, FILE *fp); static void fill(int length, int max, char filler, FILE *fp);
static char* do_header(FILE *fout, PQprintOpt *po, const int nFields,
int fieldMax[], char *fieldNames[], unsigned char fieldNotNum[],
const int fs_len, PGresult *res);
/* /*
* PQclear - * PQclear -
...@@ -78,16 +81,16 @@ PQclear(PGresult* res) ...@@ -78,16 +81,16 @@ PQclear(PGresult* res)
if (res->tuples[i][j].value) if (res->tuples[i][j].value)
free(res->tuples[i][j].value); free(res->tuples[i][j].value);
} }
free(res->tuples[i]); if (res->tuples[i]) free(res->tuples[i]);
} }
free(res->tuples); if (res->tuples) free(res->tuples);
/* free all the attributes */ /* free all the attributes */
for (i=0;i<res->numAttributes;i++) { for (i=0;i<res->numAttributes;i++) {
if (res->attDescs[i].name) if (res->attDescs[i].name)
free(res->attDescs[i].name); free(res->attDescs[i].name);
} }
free(res->attDescs); if (res->attDescs) free(res->attDescs);
/* free the structure itself */ /* free the structure itself */
free(res); free(res);
...@@ -590,8 +593,6 @@ PQexec(PGconn* conn, const char* query) ...@@ -590,8 +593,6 @@ PQexec(PGconn* conn, const char* query)
return(result); return(result);
} }
/* /*
* PQnotifies * PQnotifies
* returns a PGnotify* structure of the latest async notification * returns a PGnotify* structure of the latest async notification
...@@ -663,7 +664,6 @@ PQgetline(PGconn *conn, char *s, int maxlen) ...@@ -663,7 +664,6 @@ PQgetline(PGconn *conn, char *s, int maxlen)
return(1); /* returning a full buffer */ return(1); /* returning a full buffer */
} }
/* /*
* PQputline -- sends a string to the backend. * PQputline -- sends a string to the backend.
* *
...@@ -734,7 +734,6 @@ fill (int length, int max, char filler, FILE *fp) ...@@ -734,7 +734,6 @@ fill (int length, int max, char filler, FILE *fp)
} }
} }
/* /*
* PQdisplayTuples() * PQdisplayTuples()
* kept for backward compatibility * kept for backward compatibility
...@@ -973,12 +972,13 @@ do_field(PQprintOpt *po, PGresult *res, ...@@ -973,12 +972,13 @@ do_field(PQprintOpt *po, PGresult *res,
} }
static void static char*
do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[], do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
char *fieldNames[], unsigned char fieldNotNum[], char *fieldNames[], unsigned char fieldNotNum[],
const int fs_len, char *border, PGresult *res) { const int fs_len, PGresult *res) {
int j; /* for loop index */ int j; /* for loop index */
char *border=NULL;
if (po->html3) if (po->html3)
fputs("<tr>", fout); fputs("<tr>", fout);
...@@ -986,15 +986,17 @@ do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[], ...@@ -986,15 +986,17 @@ do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
int j; /* for loop index */ int j; /* for loop index */
int tot=0; int tot=0;
int n=0; int n=0;
char *p; char *p=NULL;
for (; n < nFields; n++) for (; n < nFields; n++)
tot+=fieldMax[n]+fs_len+(po->standard? 2: 0); tot+=fieldMax[n]+fs_len+(po->standard? 2: 0);
if (po->standard) if (po->standard)
tot+=fs_len*2+2; tot+=fs_len*2+2;
if (!(p=border=malloc(tot+1))) { border=malloc(tot+1);
if (!border) {
perror("malloc"); perror("malloc");
exit(1); exit(1);
} }
p=border;
if (po->standard) { if (po->standard) {
char *fs=po->fieldSep; char *fs=po->fieldSep;
while (*fs++) while (*fs++)
...@@ -1038,6 +1040,7 @@ do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[], ...@@ -1038,6 +1040,7 @@ do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
fputs("</tr>\n", fout); fputs("</tr>\n", fout);
else else
fprintf(fout, "\n%s\n", border); fprintf(fout, "\n%s\n", border);
return border;
} }
...@@ -1262,12 +1265,14 @@ PQprint(FILE *fout, ...@@ -1262,12 +1265,14 @@ PQprint(FILE *fout,
fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: ""); fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: "");
} }
if (po->header) if (po->header)
do_header(fout, po, nFields, fieldMax, fieldNames, fieldNotNum, border = do_header(fout, po, nFields, fieldMax, fieldNames,
fs_len, border, res); fieldNotNum, fs_len, res);
for (i = 0; i < nTups; i++) for (i = 0; i < nTups; i++)
output_row(fout, po, nFields, fields, output_row(fout, po, nFields, fields,
fieldNotNum, fieldMax, border, i); fieldNotNum, fieldMax, border, i);
free(fields); free(fields);
if (border)
free(border);
} }
if (po->header && !po->html3) if (po->header && !po->html3)
fprintf (fout, "(%d row%s)\n\n",PQntuples(res), fprintf (fout, "(%d row%s)\n\n",PQntuples(res),
...@@ -1279,8 +1284,6 @@ PQprint(FILE *fout, ...@@ -1279,8 +1284,6 @@ PQprint(FILE *fout,
pclose(fout); pclose(fout);
pqsignal(SIGPIPE, SIG_DFL); pqsignal(SIGPIPE, SIG_DFL);
} }
if (border)
free(border);
if (po->html3 && !po->expanded) if (po->html3 && !po->expanded)
fputs("</table>\n", fout); fputs("</table>\n", fout);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment