ruby-changes:62566
From: Kasumi <ko1@a...>
Date: Thu, 13 Aug 2020 20:54:26 +0900 (JST)
Subject: [ruby-changes:62566] 014a4fda54 (master): rb_str_{index, rindex}_m: Handle /\K/ in pattern
https://git.ruby-lang.org/ruby.git/commit/?id=014a4fda54 From 014a4fda54cb6897ed54ea9c44376db3459fc46e Mon Sep 17 00:00:00 2001 From: Kasumi Hanazuki <kasumi@r...> Date: Thu, 13 Aug 2020 02:26:09 +0000 Subject: rb_str_{index,rindex}_m: Handle /\K/ in pattern When the pattern Regexp given to String#index and String#rindex contain a /\K/ (lookbehind) operator, these methods return the position where the beginning of the lookbehind pattern matches, while they are expected to return the position where the \K matches. ``` # without patch "abcdbce".index(/b\Kc/) # => 1 "abcdbce".rindex(/b\Kc/) # => 4 ``` This patch fixes this problem by using BEG(0) instead of the return value of rb_reg_search. ``` # with patch "abcdbce".index(/b\Kc/) # => 2 "abcdbce".rindex(/b\Kc/) # => 5 ``` Fixes [Bug #17118] diff --git a/string.c b/string.c index e1c6e54..e984330 100644 --- a/string.c +++ b/string.c @@ -3676,8 +3676,14 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L3676 pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos, rb_enc_check(str, sub), single_byte_optimizable(str)); - pos = rb_reg_search(sub, str, pos, 0); - pos = rb_str_sublen(str, pos); + if (rb_reg_search(sub, str, pos, 0) < 0) { + return Qnil; + } else { + VALUE match = rb_backref_get(); + struct re_registers *regs = RMATCH_REGS(match); + pos = rb_str_sublen(str, BEG(0)); + return LONG2NUM(pos); + } } else { StringValue(sub); @@ -3827,9 +3833,12 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L3833 pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos, enc, single_byte_optimizable(str)); - pos = rb_reg_search(sub, str, pos, 1); - pos = rb_str_sublen(str, pos); - if (pos >= 0) return LONG2NUM(pos); + if (rb_reg_search(sub, str, pos, 1) >= 0) { + VALUE match = rb_backref_get(); + struct re_registers *regs = RMATCH_REGS(match); + pos = rb_str_sublen(str, BEG(0)); + return LONG2NUM(pos); + } } else { StringValue(sub); diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 308ba80..489eee3 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -1353,6 +1353,8 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L1353 assert_nil("foo".index(//, -100)) assert_nil($~) + + assert_equal(2, S("abcdbce").index(/b\Kc/)) end def test_insert @@ -1525,6 +1527,8 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L1527 assert_equal(3, "foo".rindex(//)) assert_equal([3, 3], $~.offset(0)) + + assert_equal(5, S("abcdbce").rindex(/b\Kc/)) end def test_rjust -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/