gzip: fix bug with any upper case custom ('-S'-specified) suffix
authorJim Meyering <meyering@fb.com>
Sat, 28 Oct 2017 21:15:04 +0000 (14:15 -0700)
committerJim Meyering <meyering@fb.com>
Sun, 29 Oct 2017 14:00:55 +0000 (07:00 -0700)
Any user-specified suffix with an upper case
letter would fail to match desired file.
* gzip.c (get_suffix): First, arrange to have only one return
point rather than two. Put a lower-cased (just-malloc'd) copy
of z_suffix in the suffix vector, and free it before returning.
* tests/upper-suffix: New file.
* tests/Makefile.am (TESTS): Add it.
* NEWS: Mention it.
Reported by meo@xenialab.it in https://bugs.gnu.org/29006

NEWS
gnulib
gzip.c
tests/Makefile.am
tests/upper-suffix [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index 4a280c47b6ab107171ad13e5e9d07de8996c44f8..2b7a168c20c4de021185eb061996beddb00378fe 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,12 @@ GNU gzip NEWS                                    -*- outline -*-
 
 ** Bug fixes
 
+  gzip -d -S SUFFIX file.SUFFIX would fail for any upper-case byte in SUFFIX.
+  E.g., before, this command would fail:
+    $ :|gzip > kT && gzip -d -S T kT
+    gzip: kT: unknown suffix -- ignored
+  [bug present since the beginning]
+
   When decompressing data in 'pack' format, gzip no longer mishandles
   leading zeros in the end-of-block code.  [bug introduced in gzip-1.6]
 
diff --git a/gnulib b/gnulib
index b86cc86ae41e68d0484c5c3957b867e4725bb986..4f0a093a593d37233c262c66ba82d8bc6b780b23 160000 (submodule)
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit b86cc86ae41e68d0484c5c3957b867e4725bb986
+Subproject commit 4f0a093a593d37233c262c66ba82d8bc6b780b23
diff --git a/gzip.c b/gzip.c
index 09a16503aa75f812940a8e63e562396cc0e46911..cfc4fe3a2a7ff70ea28662cd52aef87c4b9257d7 100644 (file)
--- a/gzip.c
+++ b/gzip.c
@@ -77,6 +77,7 @@ static char const *const license_msg[] = {
 #include "ignore-value.h"
 #include "stat-time.h"
 #include "version.h"
+#include "xalloc.h"
 #include "yesno.h"
 
                 /* configuration */
@@ -1180,9 +1181,12 @@ local char *get_suffix(name)
             break;
           }
       }
+
+    char *z_lower = xstrdup(z_suffix);
+    strlwr(z_lower);
     known_suffixes[suffix_of_builtin
                    ? sizeof known_suffixes / sizeof *known_suffixes - 2
-                   : 0] = z_suffix;
+                   : 0] = z_lower;
     suf = known_suffixes + suffix_of_builtin;
 
     nlen = strlen(name);
@@ -1193,15 +1197,18 @@ local char *get_suffix(name)
     }
     strlwr(suffix);
     slen = strlen(suffix);
+    char *match = NULL;
     do {
        int s = strlen(*suf);
        if (slen > s && ! ISSLASH (suffix[slen - s - 1])
            && strequ(suffix + slen - s, *suf)) {
-           return name+nlen-s;
+           match = name+nlen-s;
+           break;
        }
     } while (*++suf != NULL);
+    free(z_lower);
 
-    return NULL;
+    return match;
 }
 
 
index 3b1c82458a3065859608714da081097e0a6ef9b5..ed5dfdf35ac9aec0d4e08568b3127009b5a2658d 100644 (file)
@@ -29,6 +29,7 @@ TESTS =                                       \
   trailing-nul                         \
   unpack-invalid                       \
   unpack-valid                         \
+  upper-suffix                         \
   z-suffix                             \
   zdiff                                        \
   zgrep-f                              \
diff --git a/tests/upper-suffix b/tests/upper-suffix
new file mode 100755 (executable)
index 0000000..b48270e
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Ensure an upper-case user-specified suffix works as expected.
+# This test would have failed in gzip-1.18
+
+# Copyright 2017 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+# limit so don't run it by default.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+
+# Use a suffix of "T":
+:|gzip > kT || framework_failure_
+
+fail=0
+gzip -d -S T kT > out 2> err || fail=1
+
+test -f k || fail=1
+compare /dev/null out || fail=1
+compare /dev/null err || fail=1
+
+Exit $fail