[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#24385: [INSTALLED PATCH] gzip: fix some Y2038 etc. bugs
From: |
Paul Eggert |
Subject: |
bug#24385: [INSTALLED PATCH] gzip: fix some Y2038 etc. bugs |
Date: |
Tue, 6 Sep 2016 14:53:53 -0700 |
* NEWS: Document this.
* gzip.c (get_method): Warn about out-of-range MTIME,
and ignore it instead of relying on possibly-undefined behavior.
* tests/Makefile.am (TESTS): Add timestamp.
* tests/timestamp: New test.
* zip.c (zip): Warn about out-of-range file time stamp.
---
NEWS | 6 ++++++
gzip.c | 11 +++++++++--
tests/Makefile.am | 1 +
tests/timestamp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
zip.c | 12 +++++++++---
5 files changed, 77 insertions(+), 5 deletions(-)
create mode 100755 tests/timestamp
diff --git a/NEWS b/NEWS
index 8c81f5c..6532550 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,12 @@ GNU gzip NEWS -*- outline
-*-
** Bug fixes
+ gzip now warns about file time stamps out of gzip range, or out of
+ time_t range, instead of silently continuing, sometimes with
+ undefined behavior. This affects time stamps before 1970 or after
+ 2106, and time stamps after 2038 on 32-bit platforms.
+ [bug present since the beginning]
+
Support for VMS and Amiga has been removed. It was not working anyway,
and it reportedly caused file name glitches on MS-Windowsish platforms.
diff --git a/gzip.c b/gzip.c
index 0d0953c..0fca5a3 100644
--- a/gzip.c
+++ b/gzip.c
@@ -1537,8 +1537,15 @@ local int get_method(in)
stamp |= ((ulg)get_byte()) << 24;
if (stamp != 0 && !no_time)
{
- time_stamp.tv_sec = stamp;
- time_stamp.tv_nsec = 0;
+ if (stamp <= TYPE_MAXIMUM (time_t))
+ {
+ time_stamp.tv_sec = stamp;
+ time_stamp.tv_nsec = 0;
+ }
+ else
+ WARN ((stderr,
+ "%s: %s: MTIME %lu out of range for this platform\n",
+ program_name, ifname, stamp));
}
magic[8] = get_byte (); /* Ignore extra flags. */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 71cf4ad..1c24886 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -25,6 +25,7 @@ TESTS = \
mixed \
null-suffix-clobber \
stdin \
+ timestamp \
trailing-nul \
unpack-invalid \
z-suffix \
diff --git a/tests/timestamp b/tests/timestamp
new file mode 100755
index 0000000..c488760
--- /dev/null
+++ b/tests/timestamp
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Exercise timestamps.
+
+# Copyright 2016 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 <http://www.gnu.org/licenses/>.
+# limit so don't run it by default.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+
+TZ=UTC0
+export TZ
+
+# On platforms supporting time stamps outside gzip's range,
+# test that gzip warns when converting them to gzip format.
+for time in 190101010000 196912312359.59 197001010000 210602070628.16; do
+ if touch -t $time in; then
+ gzip in
+ test $? = 2 || fail=1
+ fi
+ rm -f in in.gz
+done
+
+# Test that time stamps in range for gzip do not generate warnings.
+for time in 197001010000.01 203801190314.07 203801190314.08 210602070628.15; do
+ if touch -t $time in; then
+ gzip in || fail=1
+ fi
+ rm -f in in.gz
+done
+
+# On platforms that fail to support time stamps within gzip's range,
+# test that gzip warns when converting them from gzip format.
+touch -t 210602070628.15 in || {
+ printf '\037\213\10\0\377\377\377\377\0\377\3\0\0\0\0\0\0\0\0\0' >y2106.gz ||
+ framework_failure_
+ gzip -Nlv <y2106.gz
+ test $? = 2 || fail=1
+}
+
+Exit $fail
diff --git a/zip.c b/zip.c
index 793cf42..eb60409 100644
--- a/zip.c
+++ b/zip.c
@@ -54,9 +54,15 @@ int zip(in, out)
flags |= ORIG_NAME;
}
put_byte(flags); /* general flags */
- stamp = (0 <= time_stamp.tv_sec && time_stamp.tv_sec <= 0xffffffff
- ? (ulg) time_stamp.tv_sec
- : (ulg) 0);
+ if (0 < time_stamp.tv_sec && time_stamp.tv_sec <= 0xffffffff)
+ stamp = time_stamp.tv_sec;
+ else
+ {
+ /* It's intended that time stamp 0 generates this warning,
+ since gzip format reserves 0 for something else. */
+ warning ("file time stamp out of range for gzip format");
+ stamp = 0;
+ }
put_long (stamp);
/* Write deflated file to zip file */
--
2.7.4
- bug#24385: [INSTALLED PATCH] gzip: fix some Y2038 etc. bugs,
Paul Eggert <=