]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Add a "G" option to force gzip, disabling transparency in gzread(). develop
authorMark Adler <madler@alumni.caltech.edu>
Sat, 4 Apr 2026 02:10:59 +0000 (19:10 -0700)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Mon, 3 Aug 2026 17:56:40 +0000 (19:56 +0200)
If the input is not a gzip stream with this option, an error will
be returned.

Upstream: https://github.com/madler/zlib/commit/1ab1026a

gzlib.c
gzread.c
zlib-ng.h.in
zlib.h.in

diff --git a/gzlib.c b/gzlib.c
index 6a3c8106eb12e40d5254ede256cc32b550c5e9e2..26d3c04f767cc4bed45f1e6ed51ca9faa1f72b95 100644 (file)
--- 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
index e011bfba57f65e8d727284ac154ee0f9772cf28c..570a7659961a5b4741e716cf242feac6d521f930 100644 (file)
--- 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 -- */
index 16740c04a4b5484600ba84a390b73d0644f33981..44f6110c95b010471962965447bf017f9de2e9e8 100644 (file)
@@ -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
index e9ca090e882cb582248c42fd5d29220ceb087219..facd5d0534aef6a483c2dfc60ed358f1ddea23bb 100644 (file)
--- 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