From: Brian Candler Date: 2010-08-27T17:44:00+09:00 Subject: Re: Rubyzip - `dup': can't dup NilClass (TypeError) Scott Bronson wrote: > require 'open-uri' > require 'zip/zipfilesystem' > open('http://www.vim.org/scripts/download_script.php?src_id=11978', > 'rb') { |f| Zip::ZipFile.open(f) } For me (with ruby 1.8.7 and rubyzip-0.9.4) that dies with "cannot convert Tempfile to String", but if I download the zip locally and then do Zip::ZipFile.open("ert.zip") then I get the same error as you. > For some reason, read_c_dir_entry is returning nil. I haven't tried to > figure out why since I'm not familiar with the internals of a zipfile. I suggest you apply the following patch: --- rubyzip-0.9.4/lib/zip/zip.rb.orig 2010-06-16 21:38:16.755077969 +0100 +++ rubyzip-0.9.4/lib/zip/zip.rb 2010-08-27 09:34:19.673351372 +0100 @@ -658,8 +658,8 @@ entry = new(io.path) entry.read_c_dir_entry(io) return entry - rescue ZipError - return nil + #rescue ZipError + # return nil end def file_stat(path) # :nodoc: Then you get a more helpful error: /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:645:in `read_c_dir_entry': unknown file type 00 (Zip::ZipInternalError) from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:659:in `read_c_dir_entry' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1255:in `read_central_directory_entries' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1254:in `times' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1254:in `read_central_directory_entries' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1261:in `read_from_stream' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1392:in `initialize' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1392:in `open' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1392:in `initialize' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1410:in `new' from /var/lib/gems/1.8/gems/rubyzip-0.9.4/lib/zip/zip.rb:1410:in `open' To be honest, I have no idea why rubyzip is catching these errors and returning nil, instead of letting them propagate upwards. All it does is make a more obscure error later on ("cannot dup nil") With another patch: --- rubyzip-0.9.4/lib/zip/zip.rb.orig 2010-06-16 21:38:16.755077969 +0100 +++ rubyzip-0.9.4/lib/zip/zip.rb 2010-08-27 09:38:07.475854345 +0100 @@ -642,7 +642,7 @@ when 012 @ftype = :symlink else - raise ZipInternalError, "unknown file type #{'0%o' % (@externalFileAttributes >> 28)}" + raise ZipInternalError, "unknown file type #{'0%o' % (@externalFileAttributes >> 28)} for entry #{@name.inspect}" end else if name_is_directory? you can see that the affected entry is .DS_Store. That unpacks as a regular file from unix unzip. I don't know why this entry happens to have a type of 0, but you can allow it like this: --- rubyzip-0.9.4/lib/zip/zip.rb.orig 2010-06-16 21:38:16.755077969 +0100 +++ rubyzip-0.9.4/lib/zip/zip.rb 2010-08-27 09:41:14.853352187 +0100 @@ -637,12 +637,12 @@ case (@externalFileAttributes >> 28) when 04 @ftype = :directory - when 010 + when 010, 00 @ftype = :file when 012 @ftype = :symlink Anyway, since you have a good test case for this, I suggest you post it to the rubyzip mailing list or tracker, if there is one. Regards, Brian. -- Posted via http://www.ruby-forum.com/.