From cfa1b4a711dd03f824a9c3ab50911e61419d1eeb Mon Sep 17 00:00:00 2001
From: Stephen Frost <sfrost@snowman.net>
Date: Sat, 8 Feb 2014 21:25:47 -0500
Subject: [PATCH] Minor pg_dump improvements

Improve pg_dump by checking results on various fgetc() calls which
previously were unchecked, ditto for ftello.  Also clean up a couple
of very minor memory leaks by waiting to allocate structures until
after the initial check(s).

Issues spotted by Coverity.
---
 src/bin/pg_dump/pg_backup_archiver.c | 27 +++++++++++++++++++++------
 src/bin/pg_dump/pg_backup_custom.c   |  5 ++++-
 src/bin/pg_dump/pg_dump.c            |  8 ++++++--
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 7fc0288d0e3..8ea40ea7b76 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -1898,13 +1898,22 @@ _discoverArchiveFormat(ArchiveHandle *AH)
 
 	if (strncmp(sig, "PGDMP", 5) == 0)
 	{
+		int byteread;
+
 		/*
 		 * Finish reading (most of) a custom-format header.
 		 *
 		 * NB: this code must agree with ReadHead().
 		 */
-		AH->vmaj = fgetc(fh);
-		AH->vmin = fgetc(fh);
+		if ((byteread = fgetc(fh)) == EOF)
+			exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+
+		AH->vmaj = byteread;
+
+		if ((byteread = fgetc(fh)) == EOF)
+			exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+
+		AH->vmin = byteread;
 
 		/* Save these too... */
 		AH->lookahead[AH->lookaheadLen++] = AH->vmaj;
@@ -1913,7 +1922,10 @@ _discoverArchiveFormat(ArchiveHandle *AH)
 		/* Check header version; varies from V1.0 */
 		if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0)))		/* Version > 1.0 */
 		{
-			AH->vrev = fgetc(fh);
+			if ((byteread = fgetc(fh)) == EOF)
+				exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+
+			AH->vrev = byteread;
 			AH->lookahead[AH->lookaheadLen++] = AH->vrev;
 		}
 		else
@@ -1922,18 +1934,21 @@ _discoverArchiveFormat(ArchiveHandle *AH)
 		/* Make a convenient integer <maj><min><rev>00 */
 		AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
 
-		AH->intSize = fgetc(fh);
+		if ((AH->intSize = fgetc(fh)) == EOF)
+			exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
 		AH->lookahead[AH->lookaheadLen++] = AH->intSize;
 
 		if (AH->version >= K_VERS_1_7)
 		{
-			AH->offSize = fgetc(fh);
+			if ((AH->offSize = fgetc(fh)) == EOF)
+				exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
 			AH->lookahead[AH->lookaheadLen++] = AH->offSize;
 		}
 		else
 			AH->offSize = AH->intSize;
 
-		AH->format = fgetc(fh);
+		if ((AH->format = fgetc(fh)) == EOF)
+			exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
 		AH->lookahead[AH->lookaheadLen++] = AH->format;
 	}
 	else
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index 263bcd3c532..a15254a118e 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -708,6 +708,9 @@ _CloseArchive(ArchiveHandle *AH)
 	{
 		WriteHead(AH);
 		tpos = ftello(AH->FH);
+		if (tpos < 0 || errno)
+			exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
+						  strerror(errno));
 		WriteToc(AH);
 		ctx->dataStart = _getFilePos(AH, ctx);
 		WriteDataChunks(AH, NULL);
@@ -756,7 +759,7 @@ _ReopenArchive(ArchiveHandle *AH)
 
 	errno = 0;
 	tpos = ftello(AH->FH);
-	if (errno)
+	if (tpos < 0 || errno)
 		exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
 					  strerror(errno));
 
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index ebbb5b730c3..458a118dc02 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7145,7 +7145,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
 	PGresult   *res;
 	int			ntups;
 	int			i;
-	PQExpBuffer query = createPQExpBuffer();
+	PQExpBuffer query;
 	FdwInfo    *fdwinfo;
 	int			i_tableoid;
 	int			i_oid;
@@ -7163,6 +7163,8 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
 		return NULL;
 	}
 
+	query = createPQExpBuffer();
+
 	/* Make sure we are in proper schema */
 	selectSourceSchema(fout, "pg_catalog");
 
@@ -7251,7 +7253,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
 	PGresult   *res;
 	int			ntups;
 	int			i;
-	PQExpBuffer query = createPQExpBuffer();
+	PQExpBuffer query;
 	ForeignServerInfo *srvinfo;
 	int			i_tableoid;
 	int			i_oid;
@@ -7270,6 +7272,8 @@ getForeignServers(Archive *fout, int *numForeignServers)
 		return NULL;
 	}
 
+	query = createPQExpBuffer();
+
 	/* Make sure we are in proper schema */
 	selectSourceSchema(fout, "pg_catalog");
 
-- 
GitLab