Fix a backtracking problem in String#truncate_words

Fixes #19070.
This commit is contained in:
Henrik Nygren 2015-02-25 14:28:08 +02:00
parent 5a6868b617
commit ece0d25c2b
3 changed files with 15 additions and 1 deletions

@ -1,3 +1,8 @@
* Fixed a problem where String#truncate_words would get stuck with a complex
string.
*Henrik Nygren*
* Fixed a roundtrip problem with AS::SafeBuffer where primitive-like strings
will be dumped as primitives:

@ -93,7 +93,7 @@ def truncate(truncate_at, options = {})
def truncate_words(words_count, options = {})
sep = options[:separator] || /\s+/
sep = Regexp.escape(sep.to_s) unless Regexp === sep
if self =~ /\A((?:.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m
if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m
$1 + (options[:omission] || '...')
else
dup

@ -249,6 +249,15 @@ def test_truncate_words_with_separator_and_omission
assert_equal "Hello<br>Big<br>World!", "Hello<br>Big<br>World!".truncate_words(3, :omission => "[...]", :separator => '<br>')
end
def test_truncate_words_with_complex_string
Timeout.timeout(10) do
complex_string = "aa aa aaa aa aaa aaa aaa aa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaaa aaaaa aaaaa aaaaaa aa aa aa aaa aa aaa aa aa aa aa a aaa aaa \n a aaa <<s"
assert_equal complex_string.truncate_words(80), complex_string
end
rescue Timeout::Error
assert false
end
def test_truncate_multibyte
assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding(Encoding::UTF_8),
"\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding(Encoding::UTF_8).truncate(10)