diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-01-06 13:55:53 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-01-07 10:20:30 +0100 |
commit | e72b032cc1c5a8a07a99fc6522a692c36f369abc (patch) | |
tree | 710d5ddbb4f3fe8a69064b67bde9da9cf4d16b58 /src | |
parent | 09c4ec32028aff82dcec6f1c74d721f7c6279738 (diff) |
QV4MM: Fix crash caused by MarkStack overflow
MemoryManager::collectFromJSStack did push to the mark stack without
checking if there is actually still space available. To fix this, we now
drain the stack once we hit the limit.
The test case is a slightly modified version compared to the reported
one, removing one loop. This was required as our regular expression does
not throw an exception when there are too many capture groups. However,
to trigger the bug, looping was not actually necessary.
Change-Id: I4d00865f25a989c380f4f5b221f4068c80b71d2b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 2 | ||||
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 2 |
3 files changed, 8 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 23582e0ccb..c81661033a 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1263,8 +1263,11 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file) void ExecutionEngine::markObjects(MarkStack *markStack) { for (int i = 0; i < NClasses; ++i) - if (classes[i]) + if (classes[i]) { classes[i]->mark(markStack); + if (markStack->top >= markStack->limit) + markStack->drain(); + } markStack->drain(); identifierTable->markObjects(markStack); diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 4e901721cb..ae12033eb4 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -555,6 +555,8 @@ struct ValueArray { } else { while (v < end) { v->mark(markStack); + if (markStack->top >= markStack->limit) + markStack->drain(); ++v; } } diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index c7f52eac6b..a54cbed2c9 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -1219,6 +1219,8 @@ void MemoryManager::collectFromJSStack(MarkStack *markStack) const Q_ASSERT(m->inUse()); // Skip pointers to already freed objects, they are bogus as well m->mark(markStack); + if (markStack->top >= markStack->limit) + markStack->drain(); } ++v; } |