diff options
author | David Schulz <david.schulz@qt.io> | 2017-05-04 14:46:12 +0200 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2017-05-05 05:58:26 +0000 |
commit | 7e38b54525ac23c5cdbc18582e70d4a506b399d6 (patch) | |
tree | feada2b9cc374aefcb4d0d83bef0ac3892b2e438 | |
parent | 7fb81d94f40b8a9538c4521244396b5772e1cfae (diff) | |
download | qt-creator-7e38b54525ac23c5cdbc18582e70d4a506b399d6.tar.gz |
Highlighter: Fix freezing highlighter for complex context switches
Exclamation marks in context attributes are used to split the attribute
into a number of orders and an identifier. This identifier is the
context that have to be set after executing the orders. Ignoring this
context identifier could lead to an endless loop if used inside a
default context with a Rule that has set the lookAhead attribute.
Task-number: QTCREATORBUG-14611
Change-Id: I5992fa47ed2e353cbf7882bc772fdbee8f7f41f1
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r-- | src/plugins/texteditor/generichighlighter/highlighter.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp index 89150ac6d4..d3c0b47d50 100644 --- a/src/plugins/texteditor/generichighlighter/highlighter.cpp +++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp @@ -45,6 +45,7 @@ namespace { static const QLatin1String kPop("#pop"); static const QLatin1Char kBackSlash('\\'); static const QLatin1Char kHash('#'); + static const QLatin1Char kExclamationMark('!'); } class HighlighterCodeFormatterData : public CodeFormatterData @@ -414,8 +415,13 @@ void Highlighter::changeContext(const QString &contextName, const QSharedPointer<HighlightDefinition> &definition, const bool assignCurrent) { - if (contextName.startsWith(kPop)) { - const int count = contextName.splitRef(kHash, QString::SkipEmptyParts).size(); + QString identifier = contextName; + if (identifier.startsWith(kPop)) { + const QStringList complexOrder = contextName.split(kExclamationMark); + const QString orders = complexOrder.first(); + identifier = complexOrder.size() > 1 ? complexOrder[1] : QString(); + + const int count = orders.splitRef(kHash, QString::SkipEmptyParts).size(); for (int i = 0; i < count; ++i) { if (m_contexts.isEmpty()) { throw HighlighterException( @@ -434,8 +440,9 @@ void Highlighter::changeContext(const QString &contextName, setCurrentBlockState( computeState(m_leadingObservableStates.value(currentSequence))); } - } else { - const QSharedPointer<Context> &context = definition->context(contextName); + } + if (!identifier.isEmpty()) { + const QSharedPointer<Context> &context = definition->context(identifier); if (context->isDynamic()) pushDynamicContext(context); |