From bf82e58a702900c70638e8047039fdf5f12f749f Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Wed, 27 Aug 2025 18:14:27 +0200 Subject: [PATCH] patch 9.1.1700: Multiline ignorecase specific pattern does not match with 'ignorecase' Problem: a pattern that involves a backref on a different line does not match when 'ignorecase' is set (QiWei, after v9.1.0645) Solution: Use MB_STRNICMP when ignorecase is set, fix tests to close swapfiles related: #14756 fixes: #17470 closes: #18104 Signed-off-by: author Signed-off-by: Christian Brabandt --- src/regexp.c | 5 ++++- src/testdir/test_regexp_utf8.vim | 24 ++++++++++++++++++++---- src/version.c | 2 ++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/regexp.c b/src/regexp.c index 669b123a3d..dc63cccfcb 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -1569,6 +1569,7 @@ reg_nextline(void) * Returns RA_FAIL, RA_NOMATCH or RA_MATCH. * If "bytelen" is not NULL, it is set to the byte length of the match in the * last line. + * Optional: ignore case if rex.reg_ic is set. */ static int match_with_backref( @@ -1613,7 +1614,9 @@ match_with_backref( else len = (int)reg_getline_len(clnum) - ccol; - if (cstrncmp(p + ccol, rex.input, &len) != 0) + // Use case-insensitive compare if rex.reg_ic is set + if ((!rex.reg_ic && cstrncmp(p + ccol, rex.input, &len) != 0) + || (rex.reg_ic && MB_STRNICMP(p + ccol, rex.input, len) != 0)) return RA_NOMATCH; // doesn't match if (bytelen != NULL) *bytelen += len; diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim index a4353f1b4b..6eb6bf6fa3 100644 --- a/src/testdir/test_regexp_utf8.vim +++ b/src/testdir/test_regexp_utf8.vim @@ -453,7 +453,7 @@ func Run_regexp_multibyte_magic() @w call assert_equal('k œ̄ṣ́m̥̄ᾱ̆́', getline(18)) - close! + bw! endfunc func Test_regexp_multibyte_magic() @@ -471,7 +471,7 @@ func Test_split_multibyte_to_bytes() call setline(1, 'l äö üᾱ̆́') s/ \?/ /g call assert_equal(' l ä ö ü ᾱ̆́', getline(1)) - close! + bw! endfunc " Test for matchstr() with multibyte characters @@ -481,7 +481,7 @@ func Test_matchstr_multibyte() call assert_equal('בג', matchstr("אבגד", "..", 0, 2)) call assert_equal('א', matchstr("אבגד", ".", 0, 0)) call assert_equal('ג', matchstr("אבגד", ".", 4, -1)) - close! + bw! endfunc " Test for 7.4.636 @@ -492,7 +492,7 @@ func Test_search_with_end_offset() exe "normal /(/e+\" normal n"ayn call assert_equal("a\ncat(", @a) - close! + bw! endfunc " Check that "^" matches even when the line starts with a combining char @@ -614,7 +614,23 @@ func Test_search_multibyte_match_ascii() call assert_equal(['s', 'ss', 'ſſ', 'ſ'], ic_match3, "Ignorecase Collection Regex-engine: " .. &re) call assert_equal(['ſſ','ſ'], noic_match3, "No-Ignorecase Collection Regex-engine: " .. &re) endfor + set re&vim bw! endfunc +func Test_replace_multibyte_match_in_multi_lines() + new + let text = ['ab 1c', 'ab 1c', 'def', '是否 a', '是否 a', 'ghi', '是否a', '是否a', '是否 1', '是否 1'] + let expected = ['', 'def', '', 'ghi', '', ''] + for i in range(0, 2) + exe "set ignorecase re="..i + :%d _ + call setline(1, text) + :%s/\(.\+\)\n\1//g + call assert_equal(expected, getline(1, '$')) + endfor + bw! + set ignorecase&vim re&vim +endfun + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 0bcd55691c..48c5c1c3ea 100644 --- a/src/version.c +++ b/src/version.c @@ -724,6 +724,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1700, /**/ 1699, /**/