Skip to content

Commit df96b45

Browse files
committed
Fix memory string initializer to generate format that is safe for text files. Perform Emscripten optimizer cleanup pass in binary file read and write mode to not get confused by the special characters in the string initializer. Skip closure compiler when memory string initializer is used on Windows, since closure trips over when presented with such input.
1 parent a7cf1cd commit df96b45

File tree

3 files changed

+16
-12
lines changed

3 files changed

+16
-12
lines changed

tests/test_browser.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -2943,7 +2943,8 @@ def test_meminit_pairs(self):
29432943
args = ["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2", "-s", "ASSERTIONS=1"]
29442944
self.btest(d, expected='0', args=args + ["--closure", "0"])
29452945
self.btest(d, expected='0', args=args + ["--closure", "0", "-g"])
2946-
self.btest(d, expected='0', args=args + ["--closure", "1"])
2946+
if not WINDOWS: # Closure compiler fails on Windows when it receives the unexpected characters in memory string initializer.
2947+
self.btest(d, expected='0', args=args + ["--closure", "1"])
29472948

29482949
def test_meminit_big(self):
29492950
d = 'const char *data[] = {\n "'
@@ -2955,7 +2956,8 @@ def test_meminit_big(self):
29552956
args = ["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2", "-s", "ASSERTIONS=1"]
29562957
self.btest(d, expected='0', args=args + ["--closure", "0"])
29572958
self.btest(d, expected='0', args=args + ["--closure", "0", "-g"])
2958-
self.btest(d, expected='0', args=args + ["--closure", "1"])
2959+
if not WINDOWS: # Closure compiler fails on Windows when it receives the unexpected characters in memory string initializer.
2960+
self.btest(d, expected='0', args=args + ["--closure", "1"])
29592961

29602962
def test_wasm_polyfill_prototype(self):
29612963
self.clear()

tools/js_optimizer.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ def write_chunk(chunk, i):
459459
cl_sep = 'wakaUnknownBefore(); var asm=wakaUnknownAfter(global,env,buffer)\n'
460460

461461
cle = temp_files.get('.cl.js').name
462-
c = open(cle, 'w')
462+
c = open(cle, 'wb')
463463
pre_1, pre_2 = pre.split(start_asm)
464464
post_1, post_2 = post.split(end_asm)
465465
c.write(pre_1)
@@ -470,7 +470,7 @@ def write_chunk(chunk, i):
470470
if split_memory:
471471
if DEBUG: print >> sys.stderr, 'running splitMemory on shell code'
472472
cld = run_on_chunk(js_engine + [JS_OPTIMIZER, cld, 'splitMemoryShell'])
473-
f = open(cld, 'a')
473+
f = open(cld, 'ab')
474474
f.write(suffix_marker)
475475
f.close()
476476
if closure:
@@ -481,9 +481,9 @@ def write_chunk(chunk, i):
481481
if DEBUG: print >> sys.stderr, 'running cleanup on shell code'
482482
next = cld + '.cl.js'
483483
temp_files.note(next)
484-
subprocess.Popen(js_engine + [JS_OPTIMIZER, cld, 'noPrintMetadata'] + (['minifyWhitespace'] if 'minifyWhitespace' in passes else []), stdout=open(next, 'w')).communicate()
484+
subprocess.Popen(js_engine + [JS_OPTIMIZER, cld, 'noPrintMetadata'] + (['minifyWhitespace'] if 'minifyWhitespace' in passes else []), stdout=open(next, 'wb')).communicate()
485485
cld = next
486-
coutput = open(cld).read()
486+
coutput = open(cld, 'rb').read()
487487
coutput = coutput.replace('wakaUnknownBefore();', start_asm)
488488
after = 'wakaUnknownAfter'
489489
start = coutput.find(after)
@@ -492,15 +492,15 @@ def write_chunk(chunk, i):
492492
post = post_1 + end_asm + coutput[end+1:]
493493

494494
filename += '.jo.js'
495-
f = open(filename, 'w')
495+
f = open(filename, 'wb')
496496
f.write(pre);
497497
pre = None
498498

499499
if not just_concat:
500500
# sort functions by size, to make diffing easier and to improve aot times
501501
funcses = []
502502
for out_file in filenames:
503-
funcses.append(split_funcs(open(out_file).read(), False))
503+
funcses.append(split_funcs(open(out_file, 'rb').read(), False))
504504
funcs = [item for sublist in funcses for item in sublist]
505505
funcses = None
506506
def sorter(x, y):
@@ -523,11 +523,11 @@ def sorter(x, y):
523523
else:
524524
# just concat the outputs
525525
for out_file in filenames:
526-
f.write(open(out_file).read())
527-
f.write('\n')
526+
f.write(open(out_file, 'rb').read())
527+
f.write(os.linesep) # Writing in binary mode, so make sure to generate correct newline output
528528
f.write(post);
529529
# No need to write suffix: if there was one, it is inside post which exists when suffix is there
530-
f.write('\n')
530+
f.write(os.linesep)
531531
f.close()
532532

533533
return filename

tools/shared.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1939,7 +1939,9 @@ def generate_string_initializer(s):
19391939
s = s.replace('\\', '\\\\').replace("'", "\\'")
19401940
s = s.replace('\n', '\\n').replace('\r', '\\r')
19411941
def escape(x): return '\\x{:02x}'.format(ord(x.group()))
1942-
return re.sub('[\x80-\xff]', escape, s)
1942+
s = re.sub('\x00(?![0-9])', '\\0', s) # Don't allow a null byte in the generated output file.
1943+
s = re.sub('[\x00-\x1f\x80-\xff]', escape, s) # Don't allow ASCII chars 0-31 or 128-255 in the generated output file.
1944+
return s
19431945

19441946
def execute(cmd, *args, **kw):
19451947
try:

0 commit comments

Comments
 (0)