diff options
author | Kasumi Hanazuki <kasumi@rollingapple.net> | 2020-08-13 02:26:09 +0000 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-08-13 20:54:12 +0900 |
commit | 014a4fda54cb6897ed54ea9c44376db3459fc46e (patch) | |
tree | e9f9750eec6b6e644ddb0095b75fe779eb19c39f /string.c | |
parent | 5d71eed1a7f0a70db013de59cd7e95bdca0d5c0e (diff) |
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]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/3414
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 19 |
1 files changed, 14 insertions, 5 deletions
@@ -3676,8 +3676,14 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str) 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) 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); |