Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
6.8
-
None
Description
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.