Regex: Fix infinite loop with zero-length matches

console-destruction
Lukas Werling 2016-09-18 01:16:06 +02:00
parent db12ed7c99
commit 619ad27a91
1 changed files with 15 additions and 13 deletions

View File

@ -514,17 +514,18 @@ static Nillable<C4ValueArray *> FnRegexSearch(C4PropList * _this, C4String *sour
try
{
std::regex re(regex->GetCStr(), C4IntToSyntaxOption(flags));
std::smatch m;
C4ValueArray *out = new C4ValueArray();
std::string cur(source->GetCStr());
long i = 0, pos = 0;
while (std::regex_search(cur, m, re))
const auto &data = source->GetData();
size_t pos = 0;
std::cmatch m;
long i = 0;
// std::regex_iterator would be the better way to do this, but is is broken in libc++ (see LLVM bug #21597).
while (pos < data.getLength() && std::regex_search(data.getData() + pos, data.getData() + data.getLength(), m, re))
{
pos += GetCharacterCount(m.prefix().str().c_str());
(*out)[i++] = C4VInt(pos);
int char_pos = GetCharacterCount(std::string(data.getData(), pos + m.position()).c_str());
(*out)[i++] = C4VInt(char_pos);
if (flags & Regex_FirstOnly) break;
pos += GetCharacterCount(m.str().c_str());
cur = m.suffix();
pos += m.length() > 0 ? m.position() + m.length() : m.position() + 1;
}
return out;
}
@ -540,13 +541,14 @@ static Nillable<C4ValueArray *> FnRegexMatch(C4PropList * _this, C4String *sourc
try
{
std::regex re(regex->GetCStr(), C4IntToSyntaxOption(flags));
std::smatch m;
C4ValueArray *out = new C4ValueArray();
std::string cur(source->GetCStr());
const auto &data = source->GetData();
size_t pos = 0;
std::cmatch m;
long i = 0;
while (std::regex_search(cur, m, re))
while (pos < data.getLength() && std::regex_search(data.getData() + pos, data.getData() + data.getLength(), m, re))
{
C4ValueArray *match = new C4ValueArray(1);
C4ValueArray *match = new C4ValueArray(m.size());
long j = 0;
for (auto sm : m)
{
@ -554,7 +556,7 @@ static Nillable<C4ValueArray *> FnRegexMatch(C4PropList * _this, C4String *sourc
}
(*out)[i++] = C4VArray(match);
if (flags & Regex_FirstOnly) break;
cur = m.suffix();
pos += m.length() > 0 ? m.position() + m.length() : m.position() + 1;
}
return out;
}