diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-04-01 10:52:40 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-04-04 08:19:17 +0000 |
commit | 3fca319c7fbb011151f4c6d1d5ecf2ffef0589b0 (patch) | |
tree | e7f38593e5280b73d38ba1291886b41bd3b6fa86 /src | |
parent | 9b33cdd1cda7dd385b639d00649309201602de26 (diff) |
Don't crash on "else" instructions without preceding "if"
Change-Id: I85e51f9a98bae8e2617ecc0d64c14040dc4bf1b5
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/scxml/qscxmlparser.cpp | 23 | ||||
-rw-r--r-- | src/scxml/qscxmlparser_p.h | 1 |
2 files changed, 20 insertions, 4 deletions
diff --git a/src/scxml/qscxmlparser.cpp b/src/scxml/qscxmlparser.cpp index a7aca80..a0f247b 100644 --- a/src/scxml/qscxmlparser.cpp +++ b/src/scxml/qscxmlparser.cpp @@ -2005,15 +2005,15 @@ void QScxmlParserPrivate::parse() m_stack.append(pNew); } else if (elName == QLatin1String("elseif")) { if (!checkAttributes(attributes, "cond")) return; - DocumentModel::If *ifI = m_stack.last().instruction->asIf(); - Q_ASSERT(ifI); + DocumentModel::If *ifI = lastIf(); + if (!ifI) return; ifI->conditions.append(attributes.value(QLatin1String("cond")).toString()); m_stack.last().instructionContainer = m_doc->newSequence(&ifI->blocks); m_stack.append(ParserState(ParserState::ElseIf)); } else if (elName == QLatin1String("else")) { if (!checkAttributes(attributes, "")) return; - DocumentModel::If *ifI = m_stack.last().instruction->asIf(); - Q_ASSERT(ifI); + DocumentModel::If *ifI = lastIf(); + if (!ifI) return; m_stack.last().instructionContainer = m_doc->newSequence(&ifI->blocks); m_stack.append(ParserState(ParserState::Else)); } else if (elName == QLatin1String("foreach")) { @@ -2458,6 +2458,21 @@ bool QScxmlParserPrivate::maybeId(const QXmlStreamAttributes &attributes, QStrin return true; } +DocumentModel::If *QScxmlParserPrivate::lastIf() +{ + DocumentModel::Instruction *lastI = m_stack.last().instruction; + if (!lastI) { + addError(QStringLiteral("No previous instruction found for else block")); + return Q_NULLPTR; + } + DocumentModel::If *ifI = lastI->asIf(); + if (!ifI) { + addError(QStringLiteral("Previous instruction for else block is not an 'if'")); + return Q_NULLPTR; + } + return ifI; +} + bool QScxmlParserPrivate::checkAttributes(const QXmlStreamAttributes &attributes, const char *attribStr) { QString allAttrib = QString::fromLatin1(attribStr); diff --git a/src/scxml/qscxmlparser_p.h b/src/scxml/qscxmlparser_p.h index 53853c6..87f5a29 100644 --- a/src/scxml/qscxmlparser_p.h +++ b/src/scxml/qscxmlparser_p.h @@ -583,6 +583,7 @@ private: DocumentModel::AbstractState *currentParent() const; DocumentModel::XmlLocation xmlLocation() const; bool maybeId(const QXmlStreamAttributes &attributes, QString *id); + DocumentModel::If *lastIf(); bool checkAttributes(const QXmlStreamAttributes &attributes, const char *attribStr); bool checkAttributes(const QXmlStreamAttributes &attributes, QStringList requiredNames, QStringList optionalNames); |