aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-01-06 13:55:53 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-02-17 17:21:12 +0100
commit0a155d14578d01bfe02fa9383745e04bfa1e5648 (patch)
tree1efd4824e96f209765193311899fe78563b11a76 /src
parente9b4fac4e1765ea8789b17948a0a22fad7db50c0 (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. (cherry-picked from commit e72b032cc1c5a8a07a99fc6522a692c36f369abc) Change-Id: I4d00865f25a989c380f4f5b221f4068c80b71d2b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp5
-rw-r--r--src/qml/jsruntime/qv4value_p.h2
-rw-r--r--src/qml/memory/qv4mm.cpp2
3 files changed, 8 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index f9747207db..a4831422d3 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1090,8 +1090,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 ce85e48b72..128ae3528d 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -869,6 +869,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 cac68bdcaf..342e31da1b 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -1209,6 +1209,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;
}