summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-09-20 17:38:38 +0000
committerSlávek Banko <slavek.banko@axis.cz>2015-12-23 02:22:47 +0100
commit991e21f15fa6227fda6297385225e3d0315b34c1 (patch)
tree5ca8b9a28ad4588ec056690242cd29f25eeacd11
parenta1d50519d7049fc24ca1e376b3de0ae9a2ec50e0 (diff)
downloadtdelibs-991e21f15fa6227fda6297385225e3d0315b34c1.tar.gz
tdelibs-991e21f15fa6227fda6297385225e3d0315b34c1.zip
Fix accidental double-free in KJS garbage collector
This resolves Bug 2116 (cherry picked from commit 36a7df39b0f89c467fc6d9c957a7a30f20d96994)
-rw-r--r--kjs/collector.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/kjs/collector.cpp b/kjs/collector.cpp
index 2ddd635a6..2f7e0faa6 100644
--- a/kjs/collector.cpp
+++ b/kjs/collector.cpp
@@ -24,6 +24,7 @@
#include "value.h"
#include "internal.h"
#include <limits.h>
+#include <typeinfo>
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
@@ -121,7 +122,7 @@ void* Collector::allocate(size_t s)
if (heap.usedBlocks == heap.numBlocks) {
static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR;
- if (heap.numBlocks > maxNumBlocks)
+ if ((size_t)heap.numBlocks > maxNumBlocks)
return 0L;
heap.numBlocks = MAX(MIN_ARRAY_SIZE, heap.numBlocks * GROWTH_FACTOR);
heap.blocks = (CollectorBlock **)realloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock *));
@@ -222,6 +223,10 @@ bool Collector::collect()
if (!(imp->_flags & ValueImp::VI_DESTRUCTED)) {
if (!imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) {
//fprintf( stderr, "[kjs-collector] Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name());
+
+ // prevent double free
+ imp->_flags |= ValueImp::VI_DESTRUCTED;
+
// emulate destructing part of 'operator delete()'
imp->~ValueImp();
curBlock->usedCells--;