From d27585f527365bdb32f032e789ed924d6bb2dca5 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 28 Feb 2023 17:06:59 -0600
Subject: [PATCH 3/3] pg_dump: call deflateInit() in Init() rather than in
 Write()..

This resolves an issue in e9960732a causing empty LOs to be dumped
incorrectly, resulting in errors during pg_restore.
---
 src/bin/pg_dump/compress_gzip.c | 51 +++++++++++++++++----------------
 1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/src/bin/pg_dump/compress_gzip.c b/src/bin/pg_dump/compress_gzip.c
index f3f5e87c9a8..68f3111b2fe 100644
--- a/src/bin/pg_dump/compress_gzip.c
+++ b/src/bin/pg_dump/compress_gzip.c
@@ -47,31 +47,57 @@ InitCompressorZlib(CompressorState *cs,
 	ZlibCompressorState *gzipcs;
 
 	cs->readData = ReadDataFromArchiveZlib;
 	cs->writeData = WriteDataToArchiveZlib;
 	cs->end = EndCompressorZlib;
 
 	cs->compression_spec = compression_spec;
 
 	gzipcs = (ZlibCompressorState *) pg_malloc0(sizeof(ZlibCompressorState));
 
 	cs->private_data = gzipcs;
+
+	if (cs->writeF)
+	{
+		z_streamp	zp;
+		zp = gzipcs->zp = (z_streamp) pg_malloc0(sizeof(z_stream));
+		zp->zalloc = Z_NULL;
+		zp->zfree = Z_NULL;
+		zp->opaque = Z_NULL;
+
+		/*
+		 * outsize is the buffer size we tell zlib it can output to.  We
+		 * actually allocate one extra byte because some routines want to append a
+		 * trailing zero byte to the zlib output.
+		 */
+
+		gzipcs->outbuf = pg_malloc(ZLIB_OUT_SIZE + 1);
+		gzipcs->outsize = ZLIB_OUT_SIZE;
+
+		if (deflateInit(gzipcs->zp, cs->compression_spec.level) != Z_OK)
+			pg_fatal("could not initialize compression library: %s",
+					zp->msg);
+
+		/* Just be paranoid - maybe End is called after Start, with no Write */
+		zp->next_out = gzipcs->outbuf;
+		zp->avail_out = gzipcs->outsize;
+	}
 }
 
 static void
 EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
 {
 	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp;
 
-	if (gzipcs->zp)
+	if (cs->writeF != NULL)
 	{
 		zp = gzipcs->zp;
 		zp->next_in = NULL;
 		zp->avail_in = 0;
 
 		/* Flush any remaining data from zlib buffer */
 		DeflateCompressorZlib(AH, cs, true);
 
 		if (deflateEnd(zp) != Z_OK)
 			pg_fatal("could not close compression stream: %s", zp->msg);
 
@@ -123,45 +149,22 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
 
 		if (res == Z_STREAM_END)
 			break;
 	}
 }
 
 static void
 WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
 					   const void *data, size_t dLen)
 {
 	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
-	z_streamp	zp;
-
-	if (!gzipcs->zp)
-	{
-		zp = gzipcs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
-		zp->zalloc = Z_NULL;
-		zp->zfree = Z_NULL;
-		zp->opaque = Z_NULL;
-
-		/*
-		 * outsize is the buffer size we tell zlib it can output to.  We
-		 * actually allocate one extra byte because some routines want to
-		 * append a trailing zero byte to the zlib output.
-		 */
-		gzipcs->outbuf = pg_malloc(ZLIB_OUT_SIZE + 1);
-		gzipcs->outsize = ZLIB_OUT_SIZE;
-
-		if (deflateInit(zp, cs->compression_spec.level) != Z_OK)
-			pg_fatal("could not initialize compression library: %s", zp->msg);
-
-		zp->next_out = gzipcs->outbuf;
-		zp->avail_out = gzipcs->outsize;
-	}
 
 	gzipcs->zp->next_in = (void *) unconstify(void *, data);
 	gzipcs->zp->avail_in = dLen;
 	DeflateCompressorZlib(AH, cs, false);
 }
 
 static void
 ReadDataFromArchiveZlib(ArchiveHandle *AH, CompressorState *cs)
 {
 	z_streamp	zp;
 	char	   *out;
-- 
2.34.1

