replace std::regex with QRegExp

here comes the solution to std::regex randomly throwing exceptions
(3 different kind of exceptions but almost always not the same as
the last time it does for the same pattern)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-06-11 02:20:32 +03:00
parent 49c17b3abb
commit e57b68789b
2 changed files with 21 additions and 52 deletions

View file

@ -85,39 +85,19 @@ PassRefPtr<RegExp> RegExp::create(const UString& pattern, const UString& flags)
void RegExp::compile()
{
m_constructionError = std::string();
m_regExp = std::regex();
m_constructionError.clear();
m_numSubpatterns = 0;
int regexOptions = std::regex_constants::ECMAScript;
Qt::CaseSensitivity regexOptions = Qt::CaseSensitive;
if (ignoreCase())
regexOptions |= std::regex_constants::icase;
#if 0
if (multiline())
#if __cplusplus >= 201703L
regexOptions |= std::regex_constants::multiline;
#endif
#endif
regexOptions = Qt::CaseInsensitive;
m_regexPattern = std::string(m_pattern.ascii());
#ifndef QT_NO_EXCEPTIONS
try {
m_regExp = std::regex(m_regexPattern.c_str(), regexOptions);
std::sregex_iterator matchbegin = std::sregex_iterator(m_regexPattern.begin(), m_regexPattern.end(), m_regExp);
std::sregex_iterator matchend = std::sregex_iterator();
m_numSubpatterns = std::distance(matchbegin, matchend);
} catch (const std::regex_error &err) {
m_constructionError = err.what();
} catch (...) {
m_constructionError = "Exception caught during regex compilation";
m_regExp = QRegExp(QString(m_pattern), regexOptions);
if (!m_regExp.isValid()) {
m_constructionError = m_regExp.errorString().toLatin1();
return;
}
#else
// no exceptions, no way to find out if error occured
m_regExp = std::regex(m_regexPattern.c_str(), regexOptions);
std::sregex_iterator matchbegin = std::sregex_iterator(m_regexPattern.begin(), m_regexPattern.end(), m_regExp);
std::sregex_iterator matchend = std::sregex_iterator();
m_numSubpatterns = std::distance(matchbegin, matchend);
#endif
m_numSubpatterns = m_regExp.captureCount();
}
int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
@ -145,19 +125,13 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
offsetVector = ovector->data();
}
const std::string sstring = std::string(s.ascii());
#ifndef QT_NO_EXCEPTIONS
bool didmatch = false;
try {
didmatch = std::regex_match(sstring.data() + startOffset, m_regExp);
} catch (const std::regex_error &err) {
m_constructionError = err.what();
} catch (...) {
m_constructionError = "Exception caught during regex matching";
const QString qstring(s);
#if 0
if (multiline()) {
// TODO: split lines and match
}
#else
const bool didmatch = std::regex_match(sstring.data() + startOffset, m_regExp);
#endif
const bool didmatch = m_regExp.exactMatch(qstring.data() + startOffset);
if (!didmatch) {
#ifndef QT_NO_DEBUG
@ -168,13 +142,10 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
return -1;
}
std::sregex_iterator matchbegin = std::sregex_iterator(m_regexPattern.begin(), m_regexPattern.end(), m_regExp);
std::sregex_iterator matchend = std::sregex_iterator();
size_t nummatches = 0;
for (std::sregex_iterator iter = matchbegin; iter != matchend; iter++) {
const std::smatch itermatch = *iter;
offsetVector[nummatches] = itermatch.position();
offsetVector[nummatches + 1] = itermatch.length();
for (int i = 0; i < m_regExp.matchedLength(); i++) {
offsetVector[nummatches] = m_regExp.pos(i);
offsetVector[nummatches + 1] = m_regExp.cap(0).length();
offsetVector[nummatches + 2] = 0;
nummatches++;
}

View file

@ -26,7 +26,7 @@
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
#include <regex>
#include <QRegExp>
namespace JSC {
@ -42,8 +42,8 @@ namespace JSC {
const UString& pattern() const { return m_pattern; }
bool isValid() const { return m_constructionError.empty(); }
const char* errorMessage() const { return m_constructionError.c_str(); }
bool isValid() const { return m_constructionError.isEmpty(); }
const char* errorMessage() const { return m_constructionError.constData(); }
int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
unsigned numSubpatterns() const { return m_numSubpatterns; }
@ -58,11 +58,9 @@ namespace JSC {
UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
int m_flagBits;
std::string m_constructionError;
unsigned m_numSubpatterns;
std::string m_regexPattern;
std::regex m_regExp;
QRegExp m_regExp;
QByteArray m_constructionError;
};
} // namespace JSC