From: Mark Adler Date: Sat, 4 Apr 2026 02:10:59 +0000 (-0700) Subject: Add a "G" option to force gzip, disabling transparency in gzread(). X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;ds=sidebyside;p=thirdparty%2Fzlib-ng.git Add a "G" option to force gzip, disabling transparency in gzread(). If the input is not a gzip stream with this option, an error will be returned. Upstream: https://github.com/madler/zlib/commit/1ab1026a --- diff --git a/gzlib.c b/gzlib.c index 6a3c8106e..26d3c04f7 100644 --- a/gzlib.c +++ b/gzlib.c @@ -174,6 +174,9 @@ static gzFile gz_open(const void *path, int fd, const char *mode) { case 'F': state->strategy = Z_FIXED; break; + case 'G': + state->direct = -1; + break; case 'T': state->direct = 1; break; @@ -190,14 +193,25 @@ static gzFile gz_open(const void *path, int fd, const char *mode) { return NULL; } - /* can't force transparent read */ + /* direct is 0, 1 if "T", or -1 if "G" (last "G" or "T" wins) */ if (state->mode == GZ_READ) { - if (state->direct) { + if (state->direct == 1) { + /* can't force a transparent read */ gz_state_free(state); return NULL; } - state->direct = 1; /* for empty file */ + if (state->direct == 0) + /* default when reading is auto-detect of gzip vs. transparent -- + start with a transparent assumption in case of an empty file */ + state->direct = 1; + } + else if (state->direct == -1) { + /* "G" has no meaning when writing -- disallow it */ + gz_state_free(state); + return NULL; } + /* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or + appending, direct == 0 for gzip, 1 for transparent (copy in to out) */ /* save the path name for error messages */ #ifdef WIDECHAR diff --git a/gzread.c b/gzread.c index e011bfba5..570a76599 100644 --- a/gzread.c +++ b/gzread.c @@ -110,6 +110,16 @@ static int gz_look(gz_state *state) { if (state->size == 0 && gz_read_init(state) == -1) return -1; + /* if transparent reading is disabled, which would only be at the start, or + if we're looking for a gzip member after the first one, which is not at + the start, then proceed directly to look for a gzip member next */ + if (state->direct == -1) { + PREFIX(inflateReset)(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + /* get at least the magic bytes in the input buffer */ if (strm->avail_in < 2) { if (gz_avail(state) == -1) @@ -574,7 +584,7 @@ z_int32_t Z_EXPORT PREFIX(gzdirect)(gzFile file) { (void)gz_look(state); /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; + return state->direct == 1; } /* -- see zlib.h -- */ diff --git a/zlib-ng.h.in b/zlib-ng.h.in index 16740c04a..44f6110c9 100644 --- a/zlib-ng.h.in +++ b/zlib-ng.h.in @@ -1325,7 +1325,11 @@ gzFile zng_gzopen(const char *path, const char *mode); 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) 'T' will request transparent writing or - appending with no compression and not using the gzip format. + appending with no compression and not using the gzip format. 'T' cannot be + used to force transparent reading. Transparent reading is automatically + performed if there is no gzip header at the start. Transparent reading can + be disabled with the 'G' option, which will instead return an error if there + is no gzip header. "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since diff --git a/zlib.h.in b/zlib.h.in index e9ca090e8..facd5d053 100644 --- a/zlib.h.in +++ b/zlib.h.in @@ -1322,7 +1322,11 @@ Z_EXTERN gzFile Z_EXPORT gzopen(const char *path, const char *mode); 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) 'T' will request transparent writing or - appending with no compression and not using the gzip format. + appending with no compression and not using the gzip format. 'T' cannot be + used to force transparent reading. Transparent reading is automatically + performed if there is no gzip header at the start. Transparent reading can + be disabled with the 'G' option, which will instead return an error if there + is no gzip header. "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since