diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb index 5fafaf30b3..b66ff9938c 100644 --- a/ext/psych/lib/psych/scalar_scanner.rb +++ b/ext/psych/lib/psych/scalar_scanner.rb @@ -33,7 +33,7 @@ module Psych # Check for a String type, being careful not to get caught by hash keys, hex values, and # special floats (e.g., -.inf). - if string.match?(/^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\\~;=]+/) || string.match?(/\n/) + if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/) return string if string.length > 5 if string.match?(/^[^ytonf~]/i) diff --git a/test/psych/test_scalar_scanner.rb b/test/psych/test_scalar_scanner.rb index cac8b8feb1..abd5515501 100644 --- a/test/psych/test_scalar_scanner.rb +++ b/test/psych/test_scalar_scanner.rb @@ -156,5 +156,27 @@ module Psych def test_scan_plus_dot assert_equal '+.', ss.tokenize('+.') end + + class MatchCallCounter < String + attr_reader :match_call_count + + def match?(pat) + @match_call_count ||= 0 + @match_call_count += 1 + super + end + end + + def test_scan_ascii_matches_quickly + ascii = MatchCallCounter.new('abcdefghijklmnopqrstuvwxyz') + ss.tokenize(ascii) + assert_equal 1, ascii.match_call_count + end + + def test_scan_unicode_matches_quickly + unicode = MatchCallCounter.new('鳥かご関連用品') + ss.tokenize(unicode) + assert_equal 1, unicode.match_call_count + end end end