aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/corruptionCheck.js31
-rwxr-xr-xtests/runner.py31
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):