NO_DYNAMIC_EXECUTION option to disable features using eval() or new Function()
This commit is contained in:
Родитель
4ae305542c
Коммит
b2e680a109
2
emcc
2
emcc
|
@ -1320,6 +1320,8 @@ try:
|
|||
logging.warning('disabling closure because debug info was requested')
|
||||
closure = False
|
||||
|
||||
assert not (shared.Settings.NO_DYNAMIC_EXECUTION and closure), 'cannot have both NO_DYNAMIC_EXECUTION and closure compiler enabled at the same time'
|
||||
|
||||
if closure:
|
||||
shared.Settings.CLOSURE_COMPILER = 1
|
||||
assert os.path.exists(shared.CLOSURE_COMPILER), logging.error('fatal: Closure compiler (%s) does not exist', shared.CLOSURE_COMPILER)
|
||||
|
|
|
@ -312,10 +312,15 @@ var globalScope = this;
|
|||
|
||||
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
|
||||
function getCFunc(ident) {
|
||||
try {
|
||||
var func = Module['_' + ident]; // closure exported function
|
||||
if (!func) func = eval('_' + ident); // explicit lookup
|
||||
} catch(e) {
|
||||
var func = Module['_' + ident]; // closure exported function
|
||||
if (!func) {
|
||||
#if NO_DYNAMIC_EXECUTION == 0
|
||||
try {
|
||||
func = eval('_' + ident); // explicit lookup
|
||||
} catch(e) {}
|
||||
#else
|
||||
abort('NO_DYNAMIC_EXECUTION was set, cannot eval - ccall/cwrap are not functional');
|
||||
#endif
|
||||
}
|
||||
assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
|
||||
return func;
|
||||
|
@ -458,7 +463,11 @@ var cwrap, ccall;
|
|||
funcstr += JSsource['stackRestore'].body + ';';
|
||||
}
|
||||
funcstr += 'return ret})';
|
||||
#if NO_DYNAMIC_EXECUTION == 0
|
||||
return eval(funcstr);
|
||||
#else
|
||||
abort('NO_DYNAMIC_EXECUTION was set, cannot eval - ccall is not functional');
|
||||
#endif
|
||||
};
|
||||
})();
|
||||
Module["cwrap"] = cwrap;
|
||||
|
|
|
@ -418,12 +418,16 @@ var Runtime = {
|
|||
abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
|
||||
}
|
||||
}
|
||||
#if NO_DYNAMIC_EXECUTION == 0
|
||||
try {
|
||||
var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
|
||||
} catch(e) {
|
||||
Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
|
||||
throw e;
|
||||
}
|
||||
#else
|
||||
abort('NO_DYNAMIC_EXECUTION was set, cannot eval, so EM_ASM is not functional');
|
||||
#endif
|
||||
return Runtime.asmConstCache[code] = evalled;
|
||||
},
|
||||
|
||||
|
|
|
@ -502,6 +502,11 @@ var JS_CHUNK_SIZE = 10240; // Used as a maximum size before breaking up expressi
|
|||
var EXPORT_NAME = 'Module'; // Global variable to export the module as for environments without a standardized module
|
||||
// loading system (e.g. the browser and SM shell).
|
||||
|
||||
var NO_DYNAMIC_EXECUTION = 0; // When enabled, we do not emit eval() and new Function(), which disables some functionality
|
||||
// (causing runtime errors if attempted to be used), but allows the emitted code to be
|
||||
// acceptable in places that disallow dynamic code execution (chrome packaged app, non-
|
||||
// privileged firefox app, etc.)
|
||||
|
||||
var RUNNING_JS_OPTS = 0; // whether js opts will be run, after the main compiler
|
||||
|
||||
var COMPILER_ASSERTIONS = 0; // costly (slow) compile-time assertions
|
||||
|
|
|
@ -96,7 +96,9 @@ else if (ENVIRONMENT_IS_SHELL) {
|
|||
|
||||
this['{{{ EXPORT_NAME }}}'] = Module;
|
||||
|
||||
#if CLOSURE_COMPILER
|
||||
eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
|
||||
#endif
|
||||
}
|
||||
else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
|
||||
Module['read'] = function read(url) {
|
||||
|
@ -139,7 +141,11 @@ else {
|
|||
}
|
||||
|
||||
function globalEval(x) {
|
||||
#if NO_DYNAMIC_EXECUTION == 0
|
||||
eval.call(null, x);
|
||||
#else
|
||||
throw 'NO_DYNAMIC_EXECUTION was set, cannot eval';
|
||||
#endif
|
||||
}
|
||||
if (!Module['load'] == 'undefined' && Module['read']) {
|
||||
Module['load'] = function load(f) {
|
||||
|
|
|
@ -2889,3 +2889,13 @@ int main(int argc, char **argv) {
|
|||
else:
|
||||
self.assertContained('hello, world!', run_js('a.out.js'))
|
||||
|
||||
def test_no_dynamic_execution(self):
|
||||
cmd = [PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-O1', '-s', 'NO_DYNAMIC_EXECUTION=1']
|
||||
stdout, stderr = Popen(cmd, stderr=PIPE).communicate()
|
||||
self.assertContained('hello, world!', run_js('a.out.js'))
|
||||
src = open('a.out.js').read()
|
||||
assert 'eval(' not in src
|
||||
assert 'eval.' not in src
|
||||
assert 'new Function' not in src
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче