summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/zlib/zlib.c18
-rw-r--r--test/zlib/test_zlib.rb21
2 files changed, 35 insertions, 4 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 1db5bdb4d9..a1da5f8211 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -3520,6 +3520,16 @@ rb_gzfile_path(VALUE obj)
return gz->path;
}
+static VALUE
+gzfile_initialize_path_partial(VALUE obj)
+{
+ struct gzfile* gz;
+ TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
+ gz->path = rb_funcall(gz->io, id_path, 0);
+ rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
+ return Qnil;
+}
+
static void
rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
{
@@ -3628,8 +3638,8 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
rb_gzfile_ecopts(gz, opt);
if (rb_respond_to(io, id_path)) {
- gz->path = rb_funcall(gz->io, id_path, 0);
- rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
+ /* File#path may raise IOError in case when a path is unavailable */
+ rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
}
return obj;
@@ -3890,8 +3900,8 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
rb_gzfile_ecopts(gz, opt);
if (rb_respond_to(io, id_path)) {
- gz->path = rb_funcall(gz->io, id_path, 0);
- rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
+ /* File#path may raise IOError in case when a path is unavailable */
+ rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
}
return obj;
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 126fc48c90..4da3bb4fb7 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -3,6 +3,7 @@
require 'test/unit'
require 'stringio'
require 'tempfile'
+require 'tmpdir'
begin
require 'zlib'
@@ -722,6 +723,26 @@ if defined? Zlib
gz.close
}
end
+
+ if defined? File::TMPFILE
+ def test_path_tmpfile
+ sio = StringIO.new("".dup, 'w')
+ gz = Zlib::GzipWriter.new(sio)
+ gz.write "hi"
+ gz.close
+
+ File.open(Dir.mktmpdir, File::RDWR | File::TMPFILE) do |io|
+ io.write sio.string
+ io.rewind
+
+ gz = Zlib::GzipWriter.new(io)
+ assert_raise(NoMethodError) { gz.path }
+
+ gz = Zlib::GzipReader.new(io)
+ assert_raise(NoMethodError) { gz.path }
+ end
+ end
+ end
end
class TestZlibGzipReader < Test::Unit::TestCase