summaryrefslogtreecommitdiffhomepage
path: root/test/workbook/worksheet
diff options
context:
space:
mode:
authorStefan Daschek <[email protected]>2020-07-27 21:08:59 +0200
committerGitHub <[email protected]>2020-07-27 21:08:59 +0200
commitb5092ea58f15e265f6a444cd5037d148a90d66a4 (patch)
treed27a1c0ae1f4a67a9dee71f7f3806e5744cc27bd /test/workbook/worksheet
parenteb42e143ff4da05185032177369718d70cc89ff0 (diff)
downloadcaxlsx-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.rb6
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)