weshatheleopard / rubyXL

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

Failed to write workbook when a cell contains null character #409

Closed Naoya9922 closed 2 years ago

Naoya9922 commented 2 years ago

Thank you for maintaining this awesome gem.

I have noticed that when a cell contains null character(\x00), it fails to write workbook with the error saying "string contains null byte (ArgumentError)". Is it better to replace to another character when a cell contains null character?

Gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    mini_portile2 (2.7.1)
    nokogiri (1.13.0)
      mini_portile2 (~> 2.7.0)
      racc (~> 1.4)
    racc (1.6.0)
    rubyXL (3.4.18)
      nokogiri (>= 1.10.8)
      rubyzip (>= 1.3.0)
    rubyzip (2.3.2)

PLATFORMS
  ruby

DEPENDENCIES
  rubyXL

BUNDLED WITH
   2.1.4

Code to reproduce the issue

irb(main):001:0> require 'rubyXL'
=> true
irb(main):002:0> workbook = RubyXL::Workbook.new
=> #<RubyXL::Workbook:0x0000563115288c68 @local_namespaces=nil, @file_version=nil, @file_sharing=nil, @workbook_properties=#<RubyXL::WorkbookProperties:0x00005631151267f8 @loca...
irb(main):003:0> worksheet = workbook[0]
=> #<RubyXL::Worksheet:0x00005631152880b0 @local_namespaces=nil, @sheet_pr=nil, @dimension=nil, @sheet_views=nil, @sheet_format_pr=nil, @cols=<RubyXL::ColumnRanges: [] @local_n...
irb(main):004:0> worksheet.add_cell(0, 0, 0.chr)
=> #<RubyXL::Cell(0,0): "\x00", datatype="str", style_index=0>
irb(main):005:0>  workbook.write('tmp.xlsx')
Traceback (most recent call last):
       16: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:335:in `each'
       15: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:335:in `block (2 levels) in write_xml'
       14: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:324:in `write_xml'
       13: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:324:in `each_pair'
       12: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:335:in `block in write_xml'
       11: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:335:in `each'
       10: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:335:in `block (2 levels) in write_xml'
        9: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:324:in `write_xml'
        8: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:324:in `each_pair'
        7: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:331:in `block in write_xml'
        6: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/rubyXL-3.4.18/lib/rubyXL/objects/ooxml_object.rb:314:in `write_xml'
        5: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/nokogiri-1.13.0-x86_64-linux/lib/nokogiri/xml/document.rb:224:in `create_element'
        4: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/nokogiri-1.13.0-x86_64-linux/lib/nokogiri/xml/document.rb:224:in `each'
        3: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/nokogiri-1.13.0-x86_64-linux/lib/nokogiri/xml/document.rb:237:in `block in create_element'
        2: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/nokogiri-1.13.0-x86_64-linux/lib/nokogiri/xml/node.rb:318:in `content='
        1: from /home/naoya/.anyenv/envs/rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/nokogiri-1.13.0-x86_64-linux/lib/nokogiri/xml/node.rb:318:in `encode_special_chars'
ArgumentError (string contains null byte)
weshatheleopard commented 2 years ago

@Naoya9922 This is a very interesting situation... I'm not even sure if Excel allows strings with null bytes, to begin with... How did you run into this problem? Did you open an existing workbook and tried to save it? Or?

But, either way, this error is not of RubyXL per se, but of nokogiri, so you should ask its authors.

Here's the minimal code to reproduce:

require 'nokogiri'
xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
xml.create_element("somehing", {}, "test" + 0.chr + "test")

Actually, I found this