diff options
| author | Stefan Daschek <[email protected]> | 2020-07-27 21:08:59 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-07-27 21:08:59 +0200 |
| commit | b5092ea58f15e265f6a444cd5037d148a90d66a4 (patch) | |
| tree | d27a1c0ae1f4a67a9dee71f7f3806e5744cc27bd /test/workbook/worksheet | |
| parent | eb42e143ff4da05185032177369718d70cc89ff0 (diff) | |
| download | caxlsx-b5092ea58f15e265f6a444cd5037d148a90d66a4.tar.gz caxlsx-b5092ea58f15e265f6a444cd5037d148a90d66a4.zip | |
Fix type detection for floats with out-of-rage exponents (#54)
Prior to this change, strings like "1e12345" would be interpreted as float values, regardless of the actual value of the exponent (which easily could be out of range for Ruby).
In case the exponent was greater than `Float::MAX_10_EXP` (usually 308), this would result in a cell of type `:float` containing the literal string `"Infinity"`. Excel can not parse such cells and therefore gives a “corrupt data” error.
In case the exponent was less than `Float::MIN_10_EXP` (usually -307) the cell would contain `0.0`. This does not result in Excel throwing an error, but probably isn't the expected result either.
Note that this problem is quite likely to happen when creating a worksheet with hexadecimal strings, because e.g. "1234e567" is a perfectly valid hex value.
The additional range check of the exponent introduces a slight performance overhead, so I decided to split the code path: I presume parsing floats with exponents < 100 (or no exponents at all) is way more common, so this code path behaves exactly like before. Only in the case of a 3 digit exponent the additional range check is introduced.
Diffstat (limited to 'test/workbook/worksheet')
| -rw-r--r-- | test/workbook/worksheet/tc_cell.rb | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/test/workbook/worksheet/tc_cell.rb b/test/workbook/worksheet/tc_cell.rb index 9e0bdc0e..d6f5aeae 100644 --- a/test/workbook/worksheet/tc_cell.rb +++ b/test/workbook/worksheet/tc_cell.rb @@ -100,6 +100,12 @@ class TestCell < Test::Unit::TestCase def test_cell_type_from_value assert_equal(@c.send(:cell_type_from_value, 1.0), :float) + assert_equal(@c.send(:cell_type_from_value, "1e1"), :float) + assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MAX_10_EXP}"), :float) + assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MAX_10_EXP + 1}"), :string) + assert_equal(@c.send(:cell_type_from_value, "1e-1"), :float) + assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MIN_10_EXP}"), :float) + assert_equal(@c.send(:cell_type_from_value, "1e#{Float::MIN_10_EXP - 1}"), :string) assert_equal(@c.send(:cell_type_from_value, 1), :integer) assert_equal(@c.send(:cell_type_from_value, Date.today), :date) assert_equal(@c.send(:cell_type_from_value, Time.now), :time) |
