zlib: fix Gzip{Writer,Reader}.new fails with a O_TMPFILE file

This commit is contained in:
Sorah Fukumori 2021-03-17 02:16:27 +09:00
Родитель a47697aa44
Коммит cf831f4918
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 6F49EB763DA8F24C
2 изменённых файлов: 35 добавлений и 4 удалений

Просмотреть файл

@ -3520,6 +3520,16 @@ rb_gzfile_path(VALUE obj)
return gz->path; 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 static void
rb_gzfile_ecopts(struct gzfile *gz, VALUE opts) 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); rb_gzfile_ecopts(gz, opt);
if (rb_respond_to(io, id_path)) { if (rb_respond_to(io, id_path)) {
gz->path = rb_funcall(gz->io, id_path, 0); /* File#path may raise IOError in case when a path is unavailable */
rb_define_singleton_method(obj, "path", rb_gzfile_path, 0); rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
} }
return obj; return obj;
@ -3890,8 +3900,8 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
rb_gzfile_ecopts(gz, opt); rb_gzfile_ecopts(gz, opt);
if (rb_respond_to(io, id_path)) { if (rb_respond_to(io, id_path)) {
gz->path = rb_funcall(gz->io, id_path, 0); /* File#path may raise IOError in case when a path is unavailable */
rb_define_singleton_method(obj, "path", rb_gzfile_path, 0); rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
} }
return obj; return obj;

Просмотреть файл

@ -3,6 +3,7 @@
require 'test/unit' require 'test/unit'
require 'stringio' require 'stringio'
require 'tempfile' require 'tempfile'
require 'tmpdir'
begin begin
require 'zlib' require 'zlib'
@ -722,6 +723,26 @@ if defined? Zlib
gz.close gz.close
} }
end 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 end
class TestZlibGzipReader < Test::Unit::TestCase class TestZlibGzipReader < Test::Unit::TestCase