diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-27 16:01:54 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-03-15 11:53:22 +0000 |
commit | 73231fe953145ac0df4e62f173e1a90076466012 (patch) | |
tree | 031a29f9c67be0f4fd903b18847d12081483e1b7 /src/qml/compiler/qv4codegen.cpp | |
parent | 93601b1fd4aae326562c6e7cfe16d5ecf2532a6a (diff) |
Unify the JavaScript parsing recursion checks
We only need to check in one central location and we can allow for more
recursion. 4k recursions seem tolerable. A common default for stack
sizes is 8MB. Each recursion step takes up to 1k stack space in debug
mode. So, exhausting this would burn about half of the available stack
size. We don't report the exact source location in this case as finding
the source location may itself trigger a deep recursion.
Fixes: QTBUG-74087
Change-Id: I43e6e20b322f6035c7136a6f381230ec285c30ae
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index b4da05eb9a..0ca452b93e 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -376,7 +376,6 @@ void Codegen::addCJump() void Codegen::statement(Statement *ast) { - RecursionDepthCheck depthCheck(this, ast->lastSourceLocation()); RegisterScope scope(this); bytecodeGenerator->setLocation(ast->firstSourceLocation()); @@ -392,7 +391,6 @@ void Codegen::statement(ExpressionNode *ast) if (! ast) { return; } else { - RecursionDepthCheck depthCheck(this, ast->lastSourceLocation()); RegisterScope scope(this); pushExpr(Result(nx)); @@ -420,7 +418,6 @@ void Codegen::condition(ExpressionNode *ast, const BytecodeGenerator::Label *ift if (!ast) return; - RecursionDepthCheck depthCheck(this, ast->lastSourceLocation()); pushExpr(Result(iftrue, iffalse, trueBlockFollowsCondition)); accept(ast); Result r = popExpr(); @@ -3825,8 +3822,14 @@ QQmlRefPointer<CompiledData::CompilationUnit> Codegen::createUnitForLoading() class Codegen::VolatileMemoryLocationScanner: protected QQmlJS::AST::Visitor { VolatileMemoryLocations locs; + Codegen *parent; public: + VolatileMemoryLocationScanner(Codegen *parent) : + QQmlJS::AST::Visitor(parent->recursionDepth()), + parent(parent) + {} + Codegen::VolatileMemoryLocations scan(AST::Node *s) { s->accept(this); @@ -3891,25 +3894,41 @@ public: } } + void throwRecursionDepthError() override + { + parent->throwRecursionDepthError(); + } + private: - void collectIdentifiers(QVector<QStringView> &ids, AST::Node *node) const { + void collectIdentifiers(QVector<QStringView> &ids, AST::Node *node) { class Collector: public QQmlJS::AST::Visitor { + private: QVector<QStringView> &ids; + VolatileMemoryLocationScanner *parent; + public: - Collector(QVector<QStringView> &ids): ids(ids) {} - virtual bool visit(IdentifierExpression *ie) { + Collector(QVector<QStringView> &ids, VolatileMemoryLocationScanner *parent) : + QQmlJS::AST::Visitor(parent->recursionDepth()), ids(ids), parent(parent) + {} + + bool visit(IdentifierExpression *ie) final { ids.append(ie->name); return false; } + + void throwRecursionDepthError() final + { + parent->throwRecursionDepthError(); + } }; - Collector collector(ids); + Collector collector(ids, this); node->accept(&collector); } }; -Codegen::VolatileMemoryLocations Codegen::scanVolatileMemoryLocations(AST::Node *ast) const +Codegen::VolatileMemoryLocations Codegen::scanVolatileMemoryLocations(AST::Node *ast) { - VolatileMemoryLocationScanner scanner; + VolatileMemoryLocationScanner scanner(this); return scanner.scan(ast); } |