diff options
-rw-r--r-- | src/corruptionCheck.js | 31 | ||||
-rwxr-xr-x | tests/runner.py | 31 |
2 files changed, 57 insertions, 5 deletions
diff --git a/src/corruptionCheck.js b/src/corruptionCheck.js index d676c290..8698b86d 100644 --- a/src/corruptionCheck.js +++ b/src/corruptionCheck.js @@ -14,6 +14,11 @@ var CorruptionChecker = { this.realFree = _free; _free = Module['_free'] = this.free; + if (typeof _realloc != 'undefined') { + this.realRealloc = _realloc; + _realloc = Module['_realloc'] = this.realloc; + } + __ATEXIT__.push({ func: function() { Module.printErr('No corruption detected, ran ' + CorruptionChecker.checks + ' checks.'); } }); @@ -42,17 +47,33 @@ var CorruptionChecker = { delete CorruptionChecker.ptrs[ptr]; CorruptionChecker.realFree(allocation); }, + realloc: function(ptr, newSize) { + //Module.print('realloc ' + ptr + ' to size ' + newSize); + if (newSize <= 0) newSize = 1; // like in malloc + if (!ptr) return CorruptionChecker.malloc(newSize); // realloc(NULL, size) forwards to malloc according to the spec + var size = CorruptionChecker.ptrs[ptr]; + assert(size); + var allocation = ptr - size*CorruptionChecker.BUFFER_FACTOR; + var newPtr = CorruptionChecker.malloc(newSize); + //Module.print('realloc ' + ptr + ' to size ' + newSize + ' is now ' + newPtr); + var newAllocation = newPtr + newSize*CorruptionChecker.BUFFER_FACTOR; + HEAPU8.set(HEAPU8.subarray(ptr, ptr + Math.min(size, newSize)), newPtr); + CorruptionChecker.free(ptr); + return newPtr; + }, canary: function(x) { return (x&127) + 10; }, - fillBuffer: function(allocation, size) { - for (var x = allocation; x < allocation + size; x++) { + fillBuffer: function(buffer, size) { + for (var x = buffer; x < buffer + size; x++) { {{{ makeSetValue('x', 0, 'CorruptionChecker.canary(x)', 'i8') }}}; } }, - checkBuffer: function(allocation, size) { - for (var x = allocation; x < allocation + size; x++) { - assert(({{{ makeGetValue('x', 0, 'i8') }}}&255) == CorruptionChecker.canary(x), 'Heap corruption detected!'); + checkBuffer: function(buffer, size) { + for (var x = buffer; x < buffer + size; x++) { + if (({{{ makeGetValue('x', 0, 'i8') }}}&255) != CorruptionChecker.canary(x)) { + assert(0, 'Heap corruption detected!' + [x, buffer, size, {{{ makeGetValue('x', 0, 'i8') }}}&255, CorruptionChecker.canary(x)]); + } } CorruptionChecker.checks++; }, diff --git a/tests/runner.py b/tests/runner.py index f0340cd0..3b2fcd58 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7250,6 +7250,37 @@ def process(filename): ''' self.do_run(src, 'missing!\nall ok\n') + def test_corruption_3(self): + if Settings.ASM_JS: return self.skip('cannot use corruption checks in asm') + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2 for actual test') + + Settings.CORRUPTION_CHECK = 1 + + # realloc + src = r''' + #include <stdlib.h> + #include <stdio.h> + #include <assert.h> + + void bye() { + printf("all ok\n"); + } + + int main(int argc, char **argv) { + atexit(bye); + + char *buffer = (char*)malloc(100); + for (int i = 0; i < 100; i++) buffer[i] = (i*i)%256; + buffer = (char*)realloc(buffer, argc + 50); + for (int i = 0; i < argc + 50; i++) { + //printf("%d : %d : %d : %d\n", i, (int)(buffer + i), buffer[i], (char)((i*i)%256)); + assert(buffer[i] == (char)((i*i)%256)); + } + return 1; + } + ''' + self.do_run(src, 'all ok\n') + ### Integration tests def test_ccall(self): |