Fix infinite loop in VString::replaceSubstr

If the replaced string was a suffix of the replacement, we used to get
an infinite loop.
This commit is contained in:
Geza Lore 2025-08-05 14:09:20 +01:00
parent 2c41a7bbf6
commit 25d968b833
3 changed files with 12 additions and 4 deletions

View File

@ -310,10 +310,11 @@ double VString::parseDouble(const string& str, bool* successp) {
string VString::replaceSubstr(const string& str, const string& from, const string& to) { string VString::replaceSubstr(const string& str, const string& from, const string& to) {
string result = str; string result = str;
const size_t len = from.size(); const size_t fromLen = from.size();
UASSERT_STATIC(len > 0, "Cannot replace empty string"); const size_t toLen = to.size();
for (size_t pos = 0; (pos = result.find(from, pos)) != string::npos; pos += len) { UASSERT_STATIC(fromLen > 0, "Cannot replace empty string");
result.replace(pos, len, to); for (size_t pos = 0; (pos = result.find(from, pos)) != string::npos; pos += toLen) {
result.replace(pos, fromLen, to);
} }
return result; return result;
} }
@ -396,6 +397,10 @@ uint64_t VString::hashMurmur(const string& str) VL_PURE {
return h; return h;
} }
void VString::selfTest() {
UASSERT_SELFTEST(const string&, VString::replaceSubstr("aa", "a", "ba"), "baba");
}
//###################################################################### //######################################################################
// VHashSha256 // VHashSha256

View File

@ -143,6 +143,8 @@ public:
static string aOrAn(const string& word) { return aOrAn(word.c_str()); } static string aOrAn(const string& word) { return aOrAn(word.c_str()); }
// Hash the string // Hash the string
static uint64_t hashMurmur(const string& str) VL_PURE; static uint64_t hashMurmur(const string& str) VL_PURE;
static void selfTest(); // Test this class
}; };
//###################################################################### //######################################################################

View File

@ -692,6 +692,7 @@ static bool verilate(const string& argString) {
if (v3Global.opt.debugSelfTest()) { if (v3Global.opt.debugSelfTest()) {
V3Os::selfTest(); V3Os::selfTest();
V3Number::selfTest(); V3Number::selfTest();
VString::selfTest();
VHashSha256::selfTest(); VHashSha256::selfTest();
VSpellCheck::selfTest(); VSpellCheck::selfTest();
V3Graph::selfTest(); V3Graph::selfTest();