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() void RegExp::compile()
{ {
m_constructionError = std::string(); m_constructionError.clear();
m_regExp = std::regex();
m_numSubpatterns = 0; m_numSubpatterns = 0;
int regexOptions = std::regex_constants::ECMAScript; Qt::CaseSensitivity regexOptions = Qt::CaseSensitive;
if (ignoreCase()) if (ignoreCase())
regexOptions |= std::regex_constants::icase; regexOptions = Qt::CaseInsensitive;
#if 0
if (multiline())
#if __cplusplus >= 201703L
regexOptions |= std::regex_constants::multiline;
#endif
#endif
m_regexPattern = std::string(m_pattern.ascii()); m_regExp = QRegExp(QString(m_pattern), regexOptions);
#ifndef QT_NO_EXCEPTIONS if (!m_regExp.isValid()) {
try { m_constructionError = m_regExp.errorString().toLatin1();
m_regExp = std::regex(m_regexPattern.c_str(), regexOptions); return;
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";
} }
#else m_numSubpatterns = m_regExp.captureCount();
// 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
} }
int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) 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(); offsetVector = ovector->data();
} }
const std::string sstring = std::string(s.ascii()); const QString qstring(s);
#ifndef QT_NO_EXCEPTIONS #if 0
bool didmatch = false; if (multiline()) {
try { // TODO: split lines and match
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";
} }
#else
const bool didmatch = std::regex_match(sstring.data() + startOffset, m_regExp);
#endif #endif
const bool didmatch = m_regExp.exactMatch(qstring.data() + startOffset);
if (!didmatch) { if (!didmatch) {
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
@ -168,13 +142,10 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
return -1; 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; size_t nummatches = 0;
for (std::sregex_iterator iter = matchbegin; iter != matchend; iter++) { for (int i = 0; i < m_regExp.matchedLength(); i++) {
const std::smatch itermatch = *iter; offsetVector[nummatches] = m_regExp.pos(i);
offsetVector[nummatches] = itermatch.position(); offsetVector[nummatches + 1] = m_regExp.cap(0).length();
offsetVector[nummatches + 1] = itermatch.length();
offsetVector[nummatches + 2] = 0; offsetVector[nummatches + 2] = 0;
nummatches++; nummatches++;
} }

View file

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