summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2019-10-25 19:15:24 -0400
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-10-31 22:23:58 +0900
commit0aaa15f6362e307c9ef636e9625027b96e577dfb (patch)
tree79aaa8a72d1077b3621210810bc3a60ffe769bbb
parentd6ed7a984c8fd991ce2614d2f228239f8eb490b5 (diff)
[ruby/zlib] Fix setting mtime to zero in GzipWriter
Before this change, it was not possible to write out zero for the timestamp part of a Gzip file's header, as calling GzipWriter#mtime with zero was ignored. Judging from the docs for `GzipWriter#mtime=`, it should be possible to indicate that no timestamp is available by calling the method with zero. https://github.com/ruby/zlib/commit/310be39cac
-rw-r--r--ext/zlib/zlib.c4
-rw-r--r--test/zlib/test_zlib.rb11
2 files changed, 14 insertions, 1 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 1d32581..a7d0bc1 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -2230,6 +2230,7 @@ struct gzfile {
#define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
#define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
#define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
+#define GZFILE_FLAG_MTIME_IS_SET (ZSTREAM_FLAG_UNUSED << 3)
#define GZFILE_IS_FINISHED(gz) \
(ZSTREAM_IS_FINISHED(&(gz)->z) && ZSTREAM_BUF_FILLED(&(gz)->z) == 0)
@@ -2516,7 +2517,7 @@ gzfile_make_header(struct gzfile *gz)
if (!NIL_P(gz->comment)) {
flags |= GZ_FLAG_COMMENT;
}
- if (gz->mtime == 0) {
+ if (!(gz->z.flags & GZFILE_FLAG_MTIME_IS_SET)) {
gz->mtime = time(0);
}
@@ -3246,6 +3247,7 @@ rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
val = rb_Integer(mtime);
gz->mtime = NUM2UINT(val);
+ gz->z.flags |= GZFILE_FLAG_MTIME_IS_SET;
return mtime;
}
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 7df53bd..7d703d1 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -488,6 +488,17 @@ if defined? Zlib
}
end
+ def test_zero_mtime
+ sio = StringIO.new
+ gz = Zlib::GzipWriter.new(sio)
+ gz.mtime = 0
+ gz.write("Hi")
+ gz.close
+ reading_io = StringIO.new(sio.string)
+ reader = Zlib::GzipReader.new(reading_io)
+ assert_equal(0, reader.mtime.to_i)
+ end
+
def test_level
Tempfile.create("test_zlib_gzip_file_level") {|t|
t.close