-
Bug
-
Resolution: Unresolved
-
P2: Important
-
6.8
-
None
This code will confuse the IndentingLineWriter because the "/" starts the regular expression detection and swallows the closing parenthesis.
context.lineTo(width / 2, height);
Following lines will be indented to the opening parenthesis.
The detection of regex consumes the state, and we need to restore it on error:
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
{
_tokenText.resize(0);
_state.validTokenText = true;
_state.patternFlags = 0;
const auto oldState = state();
const auto oldCodePtr = _codePtr;
const auto oldColumnNumber = _currentColumnNumber;
const auto oldLineNumber = _currentLineNumber;
const auto oldSkipLineFeed = _skipLinefeed;
const auto oldTokenText = _tokenText;
if (prefix == EqualPrefix)
_tokenText += u'=';
while (true) {
switch (_state.currentChar.unicode()) {
case u'/':
scanChar(); // scan the flags
_state.patternFlags = 0;
while (isIdentLetter(_state.currentChar)) {
int flag = regExpFlagFromChar(_state.currentChar);
if (flag == 0 || _state.patternFlags & flag) {
_errorMessage = QCoreApplication::translate(
"QQmlParser", "Invalid regular expression flag '%0'")
.arg(QChar(_state.currentChar));
goto error;
}
_state.patternFlags |= flag;
scanChar();
}
_tokenLength = _codePtr - _tokenStartPtr - 1;
return true;
case u'\\':
// regular expression backslash sequence
_tokenText += _state.currentChar;
scanChar();
if (_codePtr > _endPtr || isLineTerminator()) {
_errorMessage = QCoreApplication::translate(
"QQmlParser", "Unterminated regular expression backslash sequence");
goto error;
}
_tokenText += _state.currentChar;
scanChar();
break;
case u'[':
// regular expression class
_tokenText += _state.currentChar;
scanChar();
while (_codePtr <= _endPtr && !isLineTerminator()) {
if (_state.currentChar == u']')
break;
else if (_state.currentChar == u'\\') {
// regular expression backslash sequence
_tokenText += _state.currentChar;
scanChar();
if (_codePtr > _endPtr || isLineTerminator()) {
_errorMessage = QCoreApplication::translate(
"QQmlParser", "Unterminated regular expression backslash sequence");
goto error;
}
_tokenText += _state.currentChar;
scanChar();
} else {
_tokenText += _state.currentChar;
scanChar();
}
}
if (_state.currentChar != u']') {
_errorMessage = QCoreApplication::translate(
"QQmlParser", "Unterminated regular expression class");
goto error;
}
_tokenText += _state.currentChar;
scanChar(); // skip ]
break;
default:
if (_codePtr > _endPtr || isLineTerminator()) {
_errorMessage = QCoreApplication::translate(
"QQmlParser", "Unterminated regular expression literal");
goto error;
} else {
_tokenText += _state.currentChar;
scanChar();
}
} // switch
} // while
error:
//restore the state
setState(oldState);
_codePtr = oldCodePtr;
_currentColumnNumber = oldColumnNumber;
_currentLineNumber = oldLineNumber;
_skipLinefeed = oldSkipLineFeed;
_tokenText = oldTokenText;
return false;
}
This code will not fix false detections of regular expressions like this:
context.lineTo(width / 2, height); // comment
In this case " 2, height); " will be wrongly recognized as a regular expression, again swallowing the closing parenthesis so all subsequent code will be indented to the opening parenthesis, we have no solution for that.