summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2016-04-01 10:52:40 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2016-04-04 08:19:17 +0000
commit3fca319c7fbb011151f4c6d1d5ecf2ffef0589b0 (patch)
treee7f38593e5280b73d38ba1291886b41bd3b6fa86 /src
parent9b33cdd1cda7dd385b639d00649309201602de26 (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.cpp23
-rw-r--r--src/scxml/qscxmlparser_p.h1
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);