From fcb9535e8a3576f6bfcc54bdc52c195d46f32b53 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 6 Aug 2007 01:38:15 +0000
Subject: [PATCH] Fix pg_restore to guard against unexpected EOF while reading
 an archive file. Per report and partial patch from Chad Wagner.

---
 src/bin/pg_dump/pg_backup_archiver.c | 12 +++++++-----
 src/bin/pg_dump/pg_backup_custom.c   | 11 ++++++-----
 src/bin/pg_dump/pg_backup_files.c    |  9 +++++----
 src/bin/pg_dump/pg_backup_tar.c      | 13 +++++++------
 4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 981168bfa7c..c0e192e859b 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.144 2007/03/26 16:58:39 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.145 2007/08/06 01:38:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1472,7 +1472,7 @@ ReadStr(ArchiveHandle *AH)
 	int			l;
 
 	l = ReadInt(AH);
-	if (l == -1)
+	if (l < 0)
 		buf = NULL;
 	else
 	{
@@ -1480,7 +1480,9 @@ ReadStr(ArchiveHandle *AH)
 		if (!buf)
 			die_horribly(AH, modulename, "out of memory\n");
 
-		(*AH->ReadBufPtr) (AH, (void *) buf, l);
+		if ((*AH->ReadBufPtr) (AH, (void *) buf, l) != l)
+			die_horribly(AH, modulename, "unexpected end of file\n");
+
 		buf[l] = '\0';
 	}
 
@@ -2675,8 +2677,8 @@ ReadHead(ArchiveHandle *AH)
 	/* If we haven't already read the header... */
 	if (!AH->readHeader)
 	{
-
-		(*AH->ReadBufPtr) (AH, tmpMag, 5);
+		if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
+			die_horribly(AH, modulename, "unexpected end of file\n");
 
 		if (strncmp(tmpMag, "PGDMP", 5) != 0)
 			die_horribly(AH, modulename, "did not find magic string in file header\n");
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index a99dc99101b..923acce55a9 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -19,7 +19,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.38 2007/03/18 16:50:44 neilc Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.39 2007/08/06 01:38:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -712,7 +712,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
  *
  * Called by the archiver to read bytes & integers from the archive.
  * These routines are only used to read & write headers & TOC.
- *
+ * EOF should be treated as a fatal error.
  */
 static int
 _ReadByte(ArchiveHandle *AH)
@@ -720,9 +720,10 @@ _ReadByte(ArchiveHandle *AH)
 	lclContext *ctx = (lclContext *) AH->formatData;
 	int			res;
 
-	res = fgetc(AH->FH);
-	if (res != EOF)
-		ctx->filePos += 1;
+	res = getc(AH->FH);
+	if (res == EOF)
+		die_horribly(AH, modulename, "unexpected end of file\n");
+	ctx->filePos += 1;
 	return res;
 }
 
diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c
index 2b292aa5792..6520ca227aa 100644
--- a/src/bin/pg_dump/pg_backup_files.c
+++ b/src/bin/pg_dump/pg_backup_files.c
@@ -20,7 +20,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_files.c,v 1.32 2007/03/18 16:50:44 neilc Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_files.c,v 1.33 2007/08/06 01:38:15 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -395,9 +395,10 @@ _ReadByte(ArchiveHandle *AH)
 	lclContext *ctx = (lclContext *) AH->formatData;
 	int			res;
 
-	res = fgetc(AH->FH);
-	if (res != EOF)
-		ctx->filePos += 1;
+	res = getc(AH->FH);
+	if (res == EOF)
+		die_horribly(AH, modulename, "unexpected end of file\n");
+	ctx->filePos += 1;
 	return res;
 }
 
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 96287dcbe94..38b1d5e66e8 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.58 2007/03/18 16:50:44 neilc Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.59 2007/08/06 01:38:15 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -510,7 +510,7 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
 			used = avail;
 
 		/* Copy, and adjust buffer pos */
-		memcpy(buf, AH->lookahead, used);
+		memcpy(buf, AH->lookahead + AH->lookaheadPos, used);
 		AH->lookaheadPos += used;
 
 		/* Adjust required length */
@@ -766,12 +766,13 @@ static int
 _ReadByte(ArchiveHandle *AH)
 {
 	lclContext *ctx = (lclContext *) AH->formatData;
-	int			res;
-	char		c = '\0';
+	size_t		res;
+	unsigned char c;
 
 	res = tarRead(&c, 1, ctx->FH);
-	if (res != EOF)
-		ctx->filePos += res;
+	if (res != 1)
+		die_horribly(AH, modulename, "unexpected end of file\n");
+	ctx->filePos += 1;
 	return c;
 }
 
-- 
GitLab