weshatheleopard / rubyXL

Ruby lib for reading/writing/modifying .xlsx and .xlsm files
MIT License
1.27k stars 253 forks source link

Obscure error raised when calling `parse_buffer` with an empty buffer #448

Closed michalwa closed 5 months ago

michalwa commented 5 months ago

rubyXL version: 3.4.25 Ruby version: 3.2.3

Minimal reproduction:

> RubyXL::Parser.parse_buffer("")

NoMethodError: undefined method `root=' for nil:NilClass
from <RUBY PATH...>/lib/ruby/gems/3.2.0/gems/rubyXL-3.4.25/lib/rubyXL/objects/root.rb:68:in `parse_zip_file'

This makes it hard to properly handle cases where the file is empty.

weshatheleopard commented 5 months ago

I am relying on RubyZip detecting whether the data passed in is valid; and if it is not, it should raise Zip::Error. For example:

> RubyXL::Parser.parse_buffer "aaa"
Zip::Error (XLSX file format error: Zip end of central directory signature not found)

However, for whatever reason, the only place where this is violated is:

> ::Zip::File.open_buffer('')
=> #<Zip::File:0x000055cebe8d79c0 @entry_set=#<Zip::EntrySet:0x000055cebe8d6a48 @entry_set={}>, @comment="", @name=#<StringIO:0x000055cebe8d7bf0>, @create=true, @stored_entries=#<Zip::EntrySet:0x000055cebe8d6688 @entry_set={}>, @stored_comment="", @restore_ownership=false, @restore_permissions=false, @restore_times=false>

I.e. somehow RubyZip believes that empty string IS a valid ZIP file — and I have no idea why.

As such, you should take this issue to creators of rubyzip gem. And if they keep insisting that an empty string is a valid ZIP file, then I can revisit this bug.