summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNARUSE, Yui <nurse@users.noreply.github.com>2024-03-20 20:00:47 +0900
committerGitHub <noreply@github.com>2024-03-20 11:00:47 +0000
commit7ae8abc23961bf4fa143a7a2cc0bc38167d468ae (patch)
treea6b394c23f85b719d125f0cdf8364b79ca5542a1
parentbd42c1725a3bba0f97831aa3dbaa6924f506a5f3 (diff)
merge revision(s) bb59696614083660241ef272f222628cbfa95844: [Backport #20098] (#10298)
Fix [Bug #20098]: set counter value for {n,m} repetition correctly (#9391)
-rw-r--r--regexec.c5
-rw-r--r--test/ruby/test_regexp.rb8
-rw-r--r--version.h2
3 files changed, 12 insertions, 3 deletions
diff --git a/regexec.c b/regexec.c
index 741fb41278..9ba4106276 100644
--- a/regexec.c
+++ b/regexec.c
@@ -704,11 +704,11 @@ init_cache_opcodes(const regex_t* reg, OnigCacheOpcode* cache_opcodes, long* num
OnigRepeatRange *repeat_range = &reg->repeat_range[repeat_mem];
if (repeat_range->lower < repeat_range->upper) {
INC_CACHE_OPCODES;
- cache_point--;
+ cache_point -= lookaround_nesting != 0 ? 2 : 1;
}
cache_point -= num_cache_points_in_repeat;
int repeat_bounds = repeat_range->upper == 0x7fffffff ? 1 : repeat_range->upper - repeat_range->lower;
- cache_point += num_cache_points_in_repeat * repeat_range->lower + (num_cache_points_in_repeat + 1) * repeat_bounds;
+ cache_point += num_cache_points_in_repeat * repeat_range->lower + (num_cache_points_in_repeat + (lookaround_nesting != 0 ? 2 : 1)) * repeat_bounds;
OnigCacheOpcode* cache_opcodes_in_repeat = cache_opcodes - 1;
while (cache_opcodes_at_repeat <= cache_opcodes_in_repeat) {
cache_opcodes_in_repeat->num_cache_points_in_outer_repeat = num_cache_points_in_repeat;
@@ -2542,6 +2542,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
MATCH_CACHE_DEBUG;\
if (msa->match_cache_buf[match_cache_point_index] & match_cache_point_mask) {\
MATCH_CACHE_DEBUG_HIT;\
+ if (*pbegin == OP_REPEAT_INC) stkp->u.repeat.count--;\
if (cache_opcode->lookaround_nesting == 0) goto fail;\
else if (cache_opcode->lookaround_nesting < 0) {\
if (check_extended_match_cache_point(msa->match_cache_buf, match_cache_point_index, match_cache_point_mask)) {\
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 91a9f0a96c..0d6ab4682d 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -2008,6 +2008,14 @@ class TestRegexp < Test::Unit::TestCase
end
end
+ def test_bug_20098 # [Bug #20098]
+ assert /a((.|.)|bc){,4}z/.match? 'abcbcbcbcz'
+ assert /a(b+?c*){4,5}z/.match? 'abbbccbbbccbcbcz'
+ assert /a(b+?(.|.)){2,3}z/.match? 'abbbcbbbcbbbcz'
+ assert /a(b*?(.|.)[bc]){2,5}z/.match? 'abcbbbcbcccbcz'
+ assert /^(?:.+){2,4}?b|b/.match? "aaaabaa"
+ end
+
def test_linear_time_p
assert_send [Regexp, :linear_time?, /a/]
assert_send [Regexp, :linear_time?, 'a']
diff --git a/version.h b/version.h
index d7ccde988d..7fc8d20892 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 14
+#define RUBY_PATCHLEVEL 15
#include "ruby/version.h"
#include "ruby/internal/abi.h"