aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-30 01:00:08 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-30 01:00:08 +0100
commit2752a4632e94e2687655087d0d7f98b6b16e16a9 (patch)
tree3d9fe294e67cd5f5ae12a0004d467ec7b5b7bf51 /src/qml/parser
parent070eb7bdde4f9e6e814c3afc593368918fd445af (diff)
parentd0a52c72b5756787ceb6094117cd71d935badc06 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Diffstat (limited to 'src/qml/parser')
-rw-r--r--src/qml/parser/qqmljs.g10
-rw-r--r--src/qml/parser/qqmljsmemorypool_p.h14
2 files changed, 17 insertions, 7 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 6549e5bfa3..860a4e999e 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -614,8 +614,16 @@ bool Parser::parse(int startToken)
program = 0;
do {
- if (++tos == stack_size)
+ if (++tos == stack_size) {
reallocateStack();
+ if (stack_size > 10000) {
+ // We're now in some serious right-recursive stuff, which will probably result in
+ // an AST that's so deep that recursively visiting it will run out of stack space.
+ const QString msg = QCoreApplication::translate("QQmlParser", "Maximum statement or expression depth exceeded");
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
+ return false;
+ }
+ }
state_stack[tos] = action;
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h
index 9a480f1224..afd0f809da 100644
--- a/src/qml/parser/qqmljsmemorypool_p.h
+++ b/src/qml/parser/qqmljsmemorypool_p.h
@@ -88,7 +88,7 @@ public:
inline void *allocate(size_t size)
{
- size = (size + 7) & ~7;
+ size = (size + 7) & ~size_t(7);
if (Q_LIKELY(_ptr && (_ptr + size < _end))) {
void *addr = _ptr;
_ptr += size;
@@ -113,7 +113,9 @@ public:
private:
Q_NEVER_INLINE void *allocate_helper(size_t size)
{
- Q_ASSERT(size < BLOCK_SIZE);
+ size_t currentBlockSize = DEFAULT_BLOCK_SIZE;
+ while (Q_UNLIKELY(size >= currentBlockSize))
+ currentBlockSize *= 2;
if (++_blockCount == _allocatedBlocks) {
if (! _allocatedBlocks)
@@ -121,7 +123,7 @@ private:
else
_allocatedBlocks *= 2;
- _blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks);
+ _blocks = reinterpret_cast<char **>(realloc(_blocks, sizeof(char *) * size_t(_allocatedBlocks)));
Q_CHECK_PTR(_blocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index)
@@ -131,12 +133,12 @@ private:
char *&block = _blocks[_blockCount];
if (! block) {
- block = (char *) malloc(BLOCK_SIZE);
+ block = reinterpret_cast<char *>(malloc(currentBlockSize));
Q_CHECK_PTR(block);
}
_ptr = block;
- _end = _ptr + BLOCK_SIZE;
+ _end = _ptr + currentBlockSize;
void *addr = _ptr;
_ptr += size;
@@ -153,7 +155,7 @@ private:
enum
{
- BLOCK_SIZE = 8 * 1024,
+ DEFAULT_BLOCK_SIZE = 8 * 1024,
DEFAULT_BLOCK_COUNT = 8
};
};