From 93c45a96b5dd57ddc6b2d519a9c4b076c75f0fde Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Tue, 27 Oct 2026 12:12:40 +0900 Subject: [PATCH] Check remaining pattern length in str_lower_case_match A text character can case-fold to more bytes than remain in the pattern, e.g. U+00DF folds to "ss" against /s/i. Such a character cannot match, so stop there instead of comparing beyond the pattern. Reported-by: Paul Ryan (https://hackerone.com/secpaul) Co-Authored-By: Claude Mythos 5.1 --- regexec.c | 1 + test/ruby/test_regexp.rb | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/regexec.c b/regexec.c index 2dcd4fc20ad..02e79bedf01 100644 --- a/regexec.c +++ b/regexec.c @@ -4284,6 +4284,7 @@ str_lower_case_match(OnigEncoding enc, int case_fold_flag, while (t < tend) { lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf); + if (tend - t < lowlen) return 0; q = lowbuf; while (lowlen > 0) { if (*t++ != *q++) return 0; diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index 7196ad71c40..80169275576 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -1466,6 +1466,10 @@ class TestRegexp < Test::Unit::TestCase assert_match(/^\u00df$/i, "ss") #assert_match(/^(\u00df)\1$/i, "\u00dfss") # this must be bug... assert_match(/^\u00df{2}$/i, "\u00dfss") + assert_no_match(/s/i, "\u00df") + assert_no_match(/is/i, "i\u00df") + assert_no_match(/f/i, "\ufb03") + assert_match(/ss/i, "\u00df") assert_match(/^\u00c5$/i, "\u00c5") assert_match(/^\u00c5$/i, "\u00e5") assert_match(/^\u00c5$/i, "\u212b")