Repository :
https://github.com/colorer/Colorer-library
On branch : cregexp_refactoring
Link :
https://github.com/colorer/Colorer-library/commit/cc5655d76e2640fe4e4edf7b5003f91b18261ade
>---------------------------------------------------------------
commit cc5655d76e2640fe4e4edf7b5003f91b18261ade
Author: Aleksey Dobrunov <
cta...@ctapmex.com>
Date: Sun Aug 16 23:59:45 2026 +0500
Clear CRegExp first-char cache when replacing a pattern so a failed recompile cannot dangle firstNode.
>---------------------------------------------------------------
cc5655d76e2640fe4e4edf7b5003f91b18261ade
src/colorer/cregexp/cregexp.cpp | 3 +++
tests/unit/test_cregexp.cpp | 13 +++++++++++++
2 files changed, 16 insertions(+)
diff --git a/src/colorer/cregexp/cregexp.cpp b/src/colorer/cregexp/cregexp.cpp
index 089d5af..0d399db 100644
--- a/src/colorer/cregexp/cregexp.cpp
+++ b/src/colorer/cregexp/cregexp.cpp
@@ -110,6 +110,9 @@ EError CRegExp::setRELow(const UnicodeString& expr)
delete tree_root;
tree_root = nullptr;
+ firstNode = nullptr;
+ firstCharMask = {};
+ firstCharMaskUseful = false;
for (int bp = 0; bp < cnMatch; bp++) delete brnames[bp];
cMatch = 0;
diff --git a/tests/unit/test_cregexp.cpp b/tests/unit/test_cregexp.cpp
index fabff78..1a2d511 100644
--- a/tests/unit/test_cregexp.cpp
+++ b/tests/unit/test_cregexp.cpp
@@ -583,6 +583,19 @@ TEST_CASE("CRegExp canStartWith", "[cregexp]")
REQUIRE(re_cls.canStartWith('y'));
REQUIRE_FALSE(re_cls.canStartWith('a'));
}
+
+ SECTION("failed recompile does not leave a dangling first-char probe")
+ {
+ const auto good = ustr(u"/abc/");
+ const auto bad = ustr(u"/(abc/");
+ CRegExp re(&good);
+ REQUIRE(re.isOk());
+ REQUIRE(re.canStartWith('a'));
+ REQUIRE_FALSE(re.setRE(&bad));
+ REQUIRE_FALSE(re.isOk());
+ REQUIRE(re.canStartWith('a'));
+ REQUIRE(re.canStartWith('x'));
+ }
}
TEST_CASE("CRegExp stack reuse after clearRegExpStack", "[cregexp]")