"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
expose all out-of-memory errors from zlib
To:
gameoftrees@openbsd.org
Date:
Fri, 1 Sep 2023 13:25:54 +0200

Download raw body.

Thread
  • Stefan Sperling:

    expose all out-of-memory errors from zlib

Our zlib wrapper is hiding Z_MEM_ERROR from inflate() and deflate() calls.
If they occur (e.g. due to ulimit -d being set too low) we will see a generic
"decompression failed" error instead of the expected "out of memory" error.
The patch below fixes this.

ok?

diff /home/stsp/src/got
commit - 2cafc7864a7ffed14fede7310877bc28c6e7ef8f
path + /home/stsp/src/got
blob - e3bcc46c3b9a45e6960c6ddc97f2e530e28329cd
file + lib/deflate.c
--- lib/deflate.c
+++ lib/deflate.c
@@ -37,6 +37,17 @@
 #define	MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
 #endif
 
+static const struct got_error *
+wrap_deflate_error(int zerr, const char *prefix)
+{
+	if  (zerr == Z_ERRNO)
+		return got_error_from_errno(prefix);
+	if  (zerr == Z_MEM_ERROR)
+		return got_error_set_errno(ENOMEM, prefix);
+
+	return got_error(GOT_ERR_COMPRESSION);
+}
+
 const struct got_error *
 got_deflate_init(struct got_deflate_buf *zb, uint8_t *outbuf, size_t bufsize)
 {
@@ -48,15 +59,8 @@ got_deflate_init(struct got_deflate_buf *zb, uint8_t *
 	zb->z.zalloc = Z_NULL;
 	zb->z.zfree = Z_NULL;
 	zerr = deflateInit(&zb->z, Z_DEFAULT_COMPRESSION);
-	if (zerr != Z_OK) {
-		if  (zerr == Z_ERRNO)
-			return got_error_from_errno("deflateInit");
-		if  (zerr == Z_MEM_ERROR) {
-			errno = ENOMEM;
-			return got_error_from_errno("deflateInit");
-		}
-		return got_error(GOT_ERR_COMPRESSION);
-	}
+	if (zerr != Z_OK)
+		return wrap_deflate_error(zerr, "deflateInit");
 
 	zb->inlen = zb->outlen = bufsize;
 
@@ -131,7 +135,7 @@ got_deflate_read(struct got_deflate_buf *zb, FILE *f, 
 		zb->flags |= GOT_DEFLATE_F_HAVE_MORE;
 	} else {
 		if (ret != Z_STREAM_END)
-			return got_error(GOT_ERR_COMPRESSION);
+			return wrap_deflate_error(ret, "deflate");
 		zb->flags &= ~GOT_DEFLATE_F_HAVE_MORE;
 	}
 
@@ -175,7 +179,7 @@ deflate_read_mmap(struct got_deflate_buf *zb, uint8_t 
 		zb->flags |= GOT_DEFLATE_F_HAVE_MORE;
 	} else {
 		if (ret != Z_STREAM_END)
-			return got_error(GOT_ERR_COMPRESSION);
+			return wrap_deflate_error(ret, "deflate");
 		zb->flags &= ~GOT_DEFLATE_F_HAVE_MORE;
 	}
 
@@ -210,7 +214,7 @@ got_deflate_flush(struct got_deflate_buf *zb, FILE *ou
 
 		ret = deflate(z, Z_FINISH);
 		if (ret != Z_STREAM_END && ret != Z_OK)
-			return got_error(GOT_ERR_COMPRESSION);
+			return wrap_deflate_error(ret, "deflate");
 
 		avail = z->total_out - last_total_out;
 		if (avail > 0) {
blob - 60434b412cdbc4824102355a4d0931b6f95ec7ec
file + lib/inflate.c
--- lib/inflate.c
+++ lib/inflate.c
@@ -39,6 +39,17 @@
 #define	MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
 #endif
 
+static const struct got_error *
+wrap_inflate_error(int zerr, const char *prefix)
+{
+	if  (zerr == Z_ERRNO)
+		return got_error_from_errno(prefix);
+	if  (zerr == Z_MEM_ERROR)
+		return got_error_set_errno(ENOMEM, prefix);
+
+	return got_error(GOT_ERR_DECOMPRESSION);
+}
+
 const struct got_error *
 got_inflate_init(struct got_inflate_buf *zb, uint8_t *outbuf, size_t bufsize,
     struct got_inflate_checksum *csum)
@@ -51,15 +62,8 @@ got_inflate_init(struct got_inflate_buf *zb, uint8_t *
 	zb->z.zalloc = Z_NULL;
 	zb->z.zfree = Z_NULL;
 	zerr = inflateInit(&zb->z);
-	if (zerr != Z_OK) {
-		if  (zerr == Z_ERRNO)
-			return got_error_from_errno("inflateInit");
-		if  (zerr == Z_MEM_ERROR) {
-			errno = ENOMEM;
-			return got_error_from_errno("inflateInit");
-		}
-		return got_error(GOT_ERR_DECOMPRESSION);
-	}
+	if (zerr != Z_OK)
+		return wrap_inflate_error(zerr, "inflateInit");
 
 	zb->inlen = zb->outlen = bufsize;
 
@@ -157,7 +161,7 @@ got_inflate_read(struct got_inflate_buf *zb, FILE *f, 
 		zb->flags |= GOT_INFLATE_F_HAVE_MORE;
 	} else {
 		if (ret != Z_STREAM_END)
-			return got_error(GOT_ERR_DECOMPRESSION);
+			return wrap_inflate_error(ret, "inflate");
 		zb->flags &= ~GOT_INFLATE_F_HAVE_MORE;
 	}
 
@@ -227,7 +231,7 @@ got_inflate_read_fd(struct got_inflate_buf *zb, int fd
 		zb->flags |= GOT_INFLATE_F_HAVE_MORE;
 	} else {
 		if (ret != Z_STREAM_END)
-			return got_error(GOT_ERR_DECOMPRESSION);
+			return wrap_inflate_error(ret, "inflate");
 		zb->flags &= ~GOT_INFLATE_F_HAVE_MORE;
 	}
 
@@ -288,7 +292,7 @@ got_inflate_read_mmap(struct got_inflate_buf *zb, uint
 		zb->flags |= GOT_INFLATE_F_HAVE_MORE;
 	} else {
 		if (ret != Z_STREAM_END)
-			return got_error(GOT_ERR_DECOMPRESSION);
+			return wrap_inflate_error(ret, "inflate");
 		zb->flags &= ~GOT_INFLATE_F_HAVE_MORE;
 	}