Skip to content

Commit bf58b62

Browse files
authored
scriptDirectory handling improvements (#6894)
* handle the case of a missing document.currentScript, and of the MODULARIZE .bind() being overridden by `new` (see discussion in #6903). in both cases we can't find the scriptDirectory, but we should at least not crash. * generalize blob url handling in scriptDirectory computation to also handle workers
1 parent a0928aa commit bf58b62

File tree

3 files changed

+51
-11
lines changed

3 files changed

+51
-11
lines changed

emcc.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2612,8 +2612,10 @@ def modularize():
26122612
26132613
return %(EXPORT_NAME)s;
26142614
};
2615+
// When MODULARIZE, this JS may be executed later, after document.currentScript
2616+
// is gone, so we save it.
26152617
%(EXPORT_NAME)s = %(EXPORT_NAME)s.bind({
2616-
_currentScript: typeof document !== 'undefined' ? document.currentScript : undefined
2618+
_scriptDir: typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined
26172619
})%(instantiate)s;
26182620
''' % {
26192621
'EXPORT_NAME': shared.Settings.EXPORT_NAME,

src/shell.js

+17-10
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,25 @@ if (ENVIRONMENT_IS_SHELL) {
230230
#if ENVIRONMENT_MAY_BE_WEB_OR_WORKER
231231
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
232232
if (ENVIRONMENT_IS_WEB) {
233+
if (document.currentScript) {
234+
scriptDirectory = document.currentScript.src;
235+
}
236+
} else { // worker
237+
scriptDirectory = self.location.href;
238+
}
233239
#if MODULARIZE
234-
// When MODULARIZE, this JS may be executed later, after document.currentScript is gone, so we send it
235-
// using this._currentScript.
236-
var currentScript = this['_currentScript'] || document.currentScript;
237-
#else
238-
var currentScript = document.currentScript;
240+
// When MODULARIZE, this JS may be executed later, after document.currentScript
241+
// is gone, so we saved it, and we use it here instead of any other info.
242+
if (this['_scriptDir']) {
243+
scriptDirectory = this['_scriptDir'];
244+
}
239245
#endif
240-
if (currentScript.src.indexOf('blob:') !== 0) {
241-
scriptDirectory = currentScript.src.split('/').slice(0, -1).join('/') + '/';
242-
}
243-
} else if (ENVIRONMENT_IS_WORKER) {
244-
scriptDirectory = self.location.href.split('/').slice(0, -1).join('/') + '/';
246+
// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
247+
// otherwise, slice off the final part of the url to find the script directory.
248+
if (scriptDirectory.indexOf('blob:') !== 0) {
249+
scriptDirectory = scriptDirectory.split('/').slice(0, -1).join('/') + '/';
250+
} else {
251+
scriptDirectory = '';
245252
}
246253

247254
#if ENVIRONMENT

tests/test_browser.py

+31
Original file line numberDiff line numberDiff line change
@@ -3972,3 +3972,34 @@ def test_browser_run_from_different_directory_async(self):
39723972
''')
39733973

39743974
self.run_browser('test-subdir.html', None, '/report_result?0')
3975+
3976+
# Similar to `test_browser_run_from_different_directory`, but
3977+
# also also we eval the initial code, so currentScript is not present. That prevents us
3978+
# from finding the file in a subdir, but here we at least check we do not regress compared to the
3979+
# normal case of finding in the current dir.
3980+
# In addition, check for new Module(), which overrides the bind() and replaces the object
3981+
# which saved the _scriptDir. Again, we can't get the script dir that way, but at least we
3982+
# should not regress compared to the normal case.
3983+
def test_browser_modularize_no_current_script(self):
3984+
src = open(path_from_root('tests', 'browser_test_hello_world.c')).read()
3985+
open('test.c', 'w').write(self.with_report_result(src))
3986+
# compile the code with the modularize feature and the preload-file option enabled
3987+
Popen([PYTHON, EMCC, 'test.c', '-o', 'test.js', '-s', 'MODULARIZE=1']).communicate()
3988+
for creation in (
3989+
'Module();',
3990+
'new Module();'
3991+
):
3992+
print(creation)
3993+
open('test.html', 'w').write('''
3994+
<script>
3995+
setTimeout(function() {
3996+
var xhr = new XMLHttpRequest();
3997+
xhr.open('GET', 'test.js', false);
3998+
xhr.send(null);
3999+
eval(xhr.responseText);
4000+
%s
4001+
}, 1);
4002+
</script>
4003+
''' % creation)
4004+
self.run_browser('test.html', None, '/report_result?0')
4005+

0 commit comments

Comments
 (0)