Verify integrity of memory initializer using CRC-32
This is almost the standard CRC-32 algorithm, except that we omit the final XOR with -1 so that we can easily compare the result against zero. The length of the initializer is included in the data so that we don't have to worry about leading zeros (after XOR with the init value of -1). Useful read: http://www.ross.net/crc/download/crc_v3.txt
This commit is contained in:
Родитель
c388aeebe7
Коммит
6d3b9ff87a
20
emcc
20
emcc
|
@ -1357,14 +1357,28 @@ try:
|
|||
membytes.pop()
|
||||
if not membytes:
|
||||
return '';
|
||||
membytes = ''.join(map(chr, membytes))
|
||||
if not memory_init_file:
|
||||
s = membytes
|
||||
crcTable = []
|
||||
for i in range(256):
|
||||
crc = i
|
||||
for bit in range(8):
|
||||
crc = (crc >> 1) ^ ((crc & 1) * 0xedb88320)
|
||||
crcTable.append(crc)
|
||||
crc = 0xffffffff
|
||||
s = list(membytes)
|
||||
n = len(s)
|
||||
crc = crcTable[(crc ^ n) & 0xff] ^ (crc >> 8)
|
||||
crc = crcTable[(crc ^ (n >> 8)) & 0xff] ^ (crc >> 8)
|
||||
for i in s:
|
||||
crc = crcTable[(crc ^ i) & 0xff] ^ (crc >> 8)
|
||||
for i in range(4):
|
||||
s.append((crc >> (8 * i)) & 0xff)
|
||||
s = ''.join(map(chr, s))
|
||||
s = s.replace('\\', '\\\\').replace("'", "\\'")
|
||||
s = s.replace('\n', '\\n').replace('\r', '\\r')
|
||||
s = s.decode('latin1').encode('utf8')
|
||||
return "var memoryInitializer = '%s';" % s
|
||||
open(memfile, 'wb').write(membytes)
|
||||
open(memfile, 'wb').write(''.join(map(chr, membytes)))
|
||||
if DEBUG:
|
||||
# Copy into temp dir as well, so can be run there too
|
||||
shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
|
||||
|
|
|
@ -7,7 +7,23 @@ if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) (function(s) {
|
|||
#else
|
||||
if (memoryInitializer) (function(s) {
|
||||
#endif
|
||||
for (var i = 0; i < s.length; ++i) HEAPU8[STATIC_BASE + i] = s.charCodeAt(i);
|
||||
var i, n = s.length - 4;
|
||||
#if ASSERTIONS
|
||||
var crc, bit, table = new Int32Array(256);
|
||||
for (i = 0; i < 256; ++i) {
|
||||
for (crc = i, bit = 0; bit < 8; ++bit)
|
||||
crc = (crc >>> 1) ^ ((crc & 1) * 0xedb88320);
|
||||
table[i] = crc >>> 0;
|
||||
}
|
||||
crc = -1;
|
||||
crc = table[(crc ^ n) & 0xff] ^ (crc >>> 8);
|
||||
crc = table[(crc ^ (n >>> 8)) & 0xff] ^ (crc >>> 8);
|
||||
for (i = 0; i < s.length; ++i)
|
||||
crc = table[(crc ^ s.charCodeAt(i)) & 0xff] ^ (crc >>> 8);
|
||||
assert(crc === 0, "memory initializer checksum");
|
||||
#endif
|
||||
for (i = 0; i < n; ++i)
|
||||
HEAPU8[STATIC_BASE + i] = s.charCodeAt(i);
|
||||
})(memoryInitializer);
|
||||
#else
|
||||
#if MEM_INIT_METHOD == 1
|
||||
|
|
|
@ -4879,3 +4879,17 @@ int main() {
|
|||
out, err = Popen([PYTHON, EMCC, 'src.c', '-s', 'EXPORTED_FUNCTIONS=["_main", "_treecount"]', '--minify', '0', '-g4', '-Oz']).communicate()
|
||||
self.assertContained('hello, world!', run_js('a.out.js'))
|
||||
|
||||
def test_meminit_crc(self):
|
||||
with open('src.c', 'w') as f:
|
||||
f.write(r'''
|
||||
#include<stdio.h>
|
||||
int main() { printf("Mary had a little lamb.\n"); }
|
||||
''')
|
||||
out, err = Popen([PYTHON, EMCC, 'src.c', '-O2', '--memory-init-file', '0', '-s', 'MEM_INIT_METHOD=2', '-s', 'ASSERTIONS=1']).communicate()
|
||||
with open('a.out.js', 'r') as f:
|
||||
d = f.read()
|
||||
d = d.replace('Mary had', 'Paul had')
|
||||
with open('a.out.js', 'w') as f:
|
||||
f.write(d)
|
||||
out = run_js('a.out.js', assert_returncode=None, stderr=subprocess.STDOUT)
|
||||
self.assertContained('Assertion failed: memory initializer checksum', out)
|
||||
|
|
Загрузка…
Ссылка в новой задаче