Skip to content

Commit

Permalink
Improve float scalar scanner
Browse files Browse the repository at this point in the history
Previously, `+.inf` was not handled correctly. Additionally, the regexp
was checking for inf and NaN, even though these cases are handled earlier
in the condition. Added a few tests to ensure handling some missing
cases.
  • Loading branch information
tbrisker committed Aug 8, 2020
1 parent 181a727 commit 6e0e7a1
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
7 changes: 3 additions & 4 deletions lib/psych/scalar_scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ class ScalarScanner
TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/

# Taken from http://yaml.org/type/float.html
FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10)
|[-+]?\.(inf|Inf|INF)(?# infinity)
|\.(nan|NaN|NAN)(?# not a number))$/x
# Base 60, [-+]inf and NaN are handled separately
FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x

# Taken from http://yaml.org/type/int.html
INTEGER = /^(?:[-+]?0b[0-1_,]+ (?# base 2)
Expand Down Expand Up @@ -61,7 +60,7 @@ def tokenize string
rescue ArgumentError
string
end
elsif string.match?(/^\.inf$/i)
elsif string.match?(/^\+?\.inf$/i)
Float::INFINITY
elsif string.match?(/^-\.inf$/i)
-Float::INFINITY
Expand Down
12 changes: 12 additions & 0 deletions test/psych/test_scalar_scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ def test_scan_inf
assert_equal(1 / 0.0, ss.tokenize('.inf'))
end

def test_scan_plus_inf
assert_equal(1 / 0.0, ss.tokenize('+.inf'))
end

def test_scan_minus_inf
assert_equal(-1 / 0.0, ss.tokenize('-.inf'))
end
Expand Down Expand Up @@ -133,5 +137,13 @@ def test_scan_int_commas_and_underscores
assert_equal 0x123456789abcdef, ss.tokenize('0x_12_,34,_56,_789abcdef')
assert_equal 0x123456789abcdef, ss.tokenize('0x12_,34,_56,_789abcdef__')
end

def test_scan_dot
assert_equal '.', ss.tokenize('.')
end

def test_scan_plus_dot
assert_equal '+.', ss.tokenize('+.')
end
end
end

0 comments on commit 6e0e7a1

Please sign in to comment.