summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-03-18 10:31:10 +0100
committerUlf Hermann <ulf.hermann@qt.io>2019-03-18 09:56:45 +0000
commit11d01e3b74c84e465246a8f164b3f3b8ff92d8a4 (patch)
tree4be7398ef6a2c2d716f3f5de100144e30181d7ab
parentf1391564f6119973f46f0792b77fa65210ef00ae (diff)
Handle recursion depth errors when parsing JavaScript
Implementations of QQmlJS::AST::Visitor are required to do so. Fixes: QTBUG-74510 Change-Id: I061240f15ce082a05dd7829d225a5bfc3edd896a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qdoc/jscodemarker.cpp4
-rw-r--r--src/qdoc/qmlcodemarker.cpp4
-rw-r--r--src/qdoc/qmlcodeparser.cpp4
-rw-r--r--src/qdoc/qmlmarkupvisitor.cpp11
-rw-r--r--src/qdoc/qmlmarkupvisitor.h3
-rw-r--r--src/qdoc/qmlvisitor.cpp11
-rw-r--r--src/qdoc/qmlvisitor.h4
7 files changed, 41 insertions, 0 deletions
diff --git a/src/qdoc/jscodemarker.cpp b/src/qdoc/jscodemarker.cpp
index f283ab485..575ffbb58 100644
--- a/src/qdoc/jscodemarker.cpp
+++ b/src/qdoc/jscodemarker.cpp
@@ -130,6 +130,10 @@ QString JsCodeMarker::addMarkUp(const QString &code,
// unhandled source text can be output.
QmlMarkupVisitor visitor(code, pragmas, &engine);
QQmlJS::AST::Node::accept(ast, &visitor);
+ if (visitor.hasError()) {
+ location.warning(location.fileName() +
+ tr("Unable to analyze JavaScript. The output is incomplete."));
+ }
output = visitor.markedUpCode();
} else {
location.warning(location.fileName() +
diff --git a/src/qdoc/qmlcodemarker.cpp b/src/qdoc/qmlcodemarker.cpp
index 1ceba8016..a6f97f031 100644
--- a/src/qdoc/qmlcodemarker.cpp
+++ b/src/qdoc/qmlcodemarker.cpp
@@ -181,6 +181,10 @@ QString QmlCodeMarker::addMarkUp(const QString &code,
// unhandled source text can be output.
QmlMarkupVisitor visitor(code, pragmas, &engine);
QQmlJS::AST::Node::accept(ast, &visitor);
+ if (visitor.hasError()) {
+ location.warning(location.fileName() +
+ tr("Unable to analyze QML snippet. The output is incomplete."));
+ }
output = visitor.markedUpCode();
} else {
location.warning(tr("Unable to parse QML snippet: \"%1\" at line %2, column %3").arg(
diff --git a/src/qdoc/qmlcodeparser.cpp b/src/qdoc/qmlcodeparser.cpp
index 31775bb1b..882f83304 100644
--- a/src/qdoc/qmlcodeparser.cpp
+++ b/src/qdoc/qmlcodeparser.cpp
@@ -192,6 +192,10 @@ void QmlCodeParser::parseSourceFile(const Location& location, const QString& fil
metacommandsAllowed,
topicCommandsAllowed);
QQmlJS::AST::Node::accept(ast, &visitor);
+ if (visitor.hasError()) {
+ qDebug().nospace() << qPrintable(filePath) << ": Could not analyze QML file. "
+ << "The output is incomplete.";
+ }
}
foreach (const QQmlJS::DiagnosticMessage &msg, parser->diagnosticMessages()) {
qDebug().nospace() << qPrintable(filePath) << ':' << msg.loc.startLine
diff --git a/src/qdoc/qmlmarkupvisitor.cpp b/src/qdoc/qmlmarkupvisitor.cpp
index 7fd6e7c28..6d0f2470b 100644
--- a/src/qdoc/qmlmarkupvisitor.cpp
+++ b/src/qdoc/qmlmarkupvisitor.cpp
@@ -115,6 +115,11 @@ QString QmlMarkupVisitor::markedUpCode()
return output;
}
+bool QmlMarkupVisitor::hasError() const
+{
+ return hasRecursionDepthError;
+}
+
void QmlMarkupVisitor::addExtra(quint32 start, quint32 finish)
{
if (extraIndex >= extraLocations.length()) {
@@ -804,6 +809,12 @@ bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition)
QQmlJS::AST::Node::accept(definition->initializer, this);
return false;
}
+
+void QmlMarkupVisitor::throwRecursionDepthError()
+{
+ hasRecursionDepthError = true;
+}
+
#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlmarkupvisitor.h b/src/qdoc/qmlmarkupvisitor.h
index e01bf0e5d..d369454ff 100644
--- a/src/qdoc/qmlmarkupvisitor.h
+++ b/src/qdoc/qmlmarkupvisitor.h
@@ -55,6 +55,7 @@ public:
virtual ~QmlMarkupVisitor();
QString markedUpCode();
+ bool hasError() const;
bool visit(QQmlJS::AST::UiImport *) override;
void endVisit(QQmlJS::AST::UiImport *) override;
@@ -152,6 +153,7 @@ private:
void addVerbatim(QQmlJS::AST::SourceLocation first,
QQmlJS::AST::SourceLocation last = QQmlJS::AST::SourceLocation());
QString sourceText(QQmlJS::AST::SourceLocation &location);
+ void throwRecursionDepthError();
QQmlJS::Engine *engine;
QVector<ExtraType> extraTypes;
@@ -160,6 +162,7 @@ private:
QString output;
quint32 cursor;
int extraIndex;
+ bool hasRecursionDepthError = false;
};
Q_DECLARE_TYPEINFO(QmlMarkupVisitor::ExtraType, Q_PRIMITIVE_TYPE);
#endif
diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp
index d54378331..2834af2d6 100644
--- a/src/qdoc/qmlvisitor.cpp
+++ b/src/qdoc/qmlvisitor.cpp
@@ -843,6 +843,17 @@ void QmlDocVisitor::endVisit(QQmlJS::AST::UiQualifiedId* )
{
// nothing.
}
+
+void QmlDocVisitor::throwRecursionDepthError()
+{
+ hasRecursionDepthError = true;
+}
+
+bool QmlDocVisitor::hasError() const
+{
+ return hasRecursionDepthError;
+}
+
#endif
QT_END_NAMESPACE
diff --git a/src/qdoc/qmlvisitor.h b/src/qdoc/qmlvisitor.h
index 321819457..6e73171dc 100644
--- a/src/qdoc/qmlvisitor.h
+++ b/src/qdoc/qmlvisitor.h
@@ -92,6 +92,9 @@ public:
bool visit(QQmlJS::AST::UiQualifiedId *) override;
void endVisit(QQmlJS::AST::UiQualifiedId *) override;
+ void throwRecursionDepthError();
+ bool hasError() const;
+
private:
QString getFullyQualifiedId(QQmlJS::AST::UiQualifiedId *id);
QQmlJS::AST::SourceLocation precedingComment(quint32 offset) const;
@@ -112,6 +115,7 @@ private:
QSet<QString> topics_;
QSet<quint32> usedComments;
Aggregate *current;
+ bool hasRecursionDepthError = false;
};
#endif