aboutsummaryrefslogtreecommitdiffstats
path: root/string.c
diff options
context:
space:
mode:
authorKasumi Hanazuki <kasumi@rollingapple.net>2020-08-13 02:26:09 +0000
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-08-13 20:54:12 +0900
commit014a4fda54cb6897ed54ea9c44376db3459fc46e (patch)
treee9f9750eec6b6e644ddb0095b75fe779eb19c39f /string.c
parent5d71eed1a7f0a70db013de59cd7e95bdca0d5c0e (diff)
downloadruby-014a4fda54cb6897ed54ea9c44376db3459fc46e.tar.gz
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]
Diffstat (limited to 'string.c')
-rw-r--r--string.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/string.c b/string.c
index e1c6e54456..e984330b9a 100644
--- a/string.c
+++ b/string.c
@@ -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);