aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--src/Document.cxx8
-rw-r--r--test/unit/testDocument.cxx46
3 files changed, 58 insertions, 0 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 5a54725a2..7d1d9f48f 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -595,6 +595,10 @@
<a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/13442">Notepad++ Issue #13442</a>.
</li>
<li>
+ Fix incorrect substitution when searching for a regular expression backwards.
+ <a href="https://sourceforge.net/p/scintilla/bugs/2405/">Bug #2405</a>.
+ </li>
+ <li>
For Cocoa, fix invisible text on macOS 14 Sonoma.
<a href="https://sourceforge.net/p/scintilla/bugs/2402/">Bug #2402</a>.
</li>
diff --git a/src/Document.cxx b/src/Document.cxx
index 0365b24db..a45479e4b 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -3294,7 +3294,11 @@ Sci::Position BuiltinRegex::FindText(Document *doc, Sci::Position minPos, Sci::P
if ((resr.increment == -1) && !searchforLineStart) {
// Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop
+ RESearch::MatchPositions bopat{};
+ RESearch::MatchPositions eopat{};
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {
+ bopat = search.bopat;
+ eopat = search.eopat;
success = search.Execute(di, pos+1, endOfLine);
if (success) {
if (search.eopat[0] <= minPos) {
@@ -3305,6 +3309,10 @@ Sci::Position BuiltinRegex::FindText(Document *doc, Sci::Position minPos, Sci::P
}
}
}
+ if (!success) {
+ search.bopat = bopat;
+ search.eopat = eopat;
+ }
}
break;
}
diff --git a/test/unit/testDocument.cxx b/test/unit/testDocument.cxx
index 3cfb54db4..4ed1dbbbd 100644
--- a/test/unit/testDocument.cxx
+++ b/test/unit/testDocument.cxx
@@ -453,6 +453,52 @@ TEST_CASE("Document") {
REQUIRE(doc.NextPosition(15, -1) == 14);
}
+ SECTION("RegexSearchAndSubstitution") {
+ DocPlus doc("\n\r\r\n 1a\xCE\x93z \n\r\r\n 2b\xCE\x93y \n\r\r\n", CpUtf8);// 1a gamma z 2b gamma y
+ const std::string finding = R"(\d+(\w+))";
+ Sci::Position lengthFinding = finding.length();
+ Sci::Position location = doc.FindNeedle(finding, FindOption::RegExp | FindOption::Posix, &lengthFinding);
+ REQUIRE(location == 5);
+ REQUIRE(lengthFinding == 5);
+
+ const std::string_view substituteText = R"(\t\1\n)";
+ Sci::Position lengthsubstitute = substituteText.length();
+ std::string substituted = doc.document.SubstituteByPosition(substituteText.data(), &lengthsubstitute);
+ REQUIRE(lengthsubstitute == 6);
+ REQUIRE(substituted == "\ta\xCE\x93z\n");
+
+ lengthFinding = finding.length();
+ location = doc.FindNeedleReverse(finding, FindOption::RegExp | FindOption::Posix, &lengthFinding);
+ REQUIRE(location == 16);
+ REQUIRE(lengthFinding == 5);
+
+ lengthsubstitute = substituteText.length();
+ substituted = doc.document.SubstituteByPosition(substituteText.data(), &lengthsubstitute);
+ REQUIRE(lengthsubstitute == 6);
+ REQUIRE(substituted == "\tb\xCE\x93y\n");
+
+ #ifndef NO_CXX11_REGEX
+ lengthFinding = finding.length();
+ location = doc.FindNeedle(finding, FindOption::RegExp | FindOption::Cxx11RegEx, &lengthFinding);
+ REQUIRE(location == 5);
+ REQUIRE(lengthFinding == 5);
+
+ lengthsubstitute = substituteText.length();
+ substituted = doc.document.SubstituteByPosition(substituteText.data(), &lengthsubstitute);
+ REQUIRE(lengthsubstitute == 6);
+ REQUIRE(substituted == "\ta\xCE\x93z\n");
+
+ lengthFinding = finding.length();
+ location = doc.FindNeedleReverse(finding, FindOption::RegExp | FindOption::Cxx11RegEx, &lengthFinding);
+ REQUIRE(location == 16);
+ REQUIRE(lengthFinding == 5);
+
+ lengthsubstitute = substituteText.length();
+ substituted = doc.document.SubstituteByPosition(substituteText.data(), &lengthsubstitute);
+ REQUIRE(lengthsubstitute == 6);
+ REQUIRE(substituted == "\tb\xCE\x93y\n");
+ #endif
+ }
}
TEST_CASE("Words") {