Git rid of eval() in WASM wrapper
Hi again!
I used DotNetJS to create a library that exposes some common functions that we share across C# executables and an Electron app to ensure the behaviour is identical.
The problem is, the electron's app (Vortex) is blocking eval execution due to it's CSP. I did earlier some investigation about this, but I would like to double check! Is eval critical for the runtime to work or is it used only for debugging? Could we strip it's usage with some conditionals?
- [x] Waiting for https://github.com/dotnet/runtime/pull/74441
https://github.com/dotnet/runtime/issues/68374 https://github.com/dotnet/runtime/issues/59416 https://github.com/dotnet/aspnetcore/issues/37787
Based on those issues, it's fixable, but not done yet, it seems
VS Code (which is built on Electron as well, iirc) had a similar limitation, but they've removed it: https://github.com/microsoft/vscode/issues/138413
Here are the 3 eval calls I was able to find in the .NET's wasm wrapper:
https://github.com/Elringus/DotNetJS/blob/cad9a87854fd860203d25991a55bb3a68fa11229/JavaScript/dotnet-runtime/native/dotnet.js#L578 https://github.com/Elringus/DotNetJS/blob/cad9a87854fd860203d25991a55bb3a68fa11229/JavaScript/dotnet-runtime/native/dotnet.js#L640 https://github.com/Elringus/DotNetJS/blob/cad9a87854fd860203d25991a55bb3a68fa11229/JavaScript/dotnet-runtime/native/dotnet.js#L3840
— but there are probably more.
Not sure it's possible to patch it the same way we're patching out other stuff here: https://github.com/Elringus/DotNetJS/blob/cad9a87854fd860203d25991a55bb3a68fa11229/JavaScript/dotnet-runtime/scripts/compile-runtime.sh#L13-L16
I also hope to opt-out of custom .NET runtime build as soon as possible (so we can support AOT and stripping #20), which will be problematic should we further patch the wrapper.
Guess we'll have to wait until this is solved in .NET runtime.
I'll report at least my findings then.
I think that there's an additional eval call in function Function.apply(Function, i);
https://github.com/Elringus/DotNetJS/blob/cad9a87854fd860203d25991a55bb3a68fa11229/JavaScript/dotnet-runtime/native/dotnet.js#L4760
After replacing all evals with { } as you did, Vortex still had an issue with that function. After replacing it with (x, y) => () => { }, CSP wasn't triggering anymore and Vortex stared to load the module, but now there's this error Error: System.NullReferenceException: Arg_NullReferenceException, pretty sure it breaks the runtime.
From what I understand somehow an eval function is injected here
https://github.com/Elringus/DotNetJS/blob/cad9a87854fd860203d25991a55bb3a68fa11229/JavaScript/dotnet-runtime/native/dotnet.js#L4760
I manually enabled unsafe-eval for better debugging and tried some shenanigans like new Function('"use strict";return (' + keys+ ')'), but nope.
Replacing with new Function('return ' + keys); or new Function(keys) yielded an interesting error and stacktrace:
ReferenceError: converter is not defined
at eval (https://mono-wasm.invalid/variadic_converter_ii_result_unmarshaled:3:1)
which confirms that eval is used internally, as I understand.
I'm still not sure what Function.apply() does. It's safe to replace the first arg with null instead of Function, not sure why it wasn't done. Replacing the whole construction with eval(keys) works too. But as said earlier, the alternative with new Function() isn't working.
I think that there's an additional
evalcall in functionFunction.apply(Function, i);
Right, that aligns with the mono issue you've mentioned previously (https://github.com/dotnet/runtime/issues/68374); they've also mentioned the same line and a couple of others. Guess we'd have to wait when it's solved.
Oh, right, forgot about that issue. Yep, agree, can't do much here.
https://github.com/dotnet/runtime/issues/68374#issuecomment-1149742636 I guess the variable could be set at build time?
dotnet/runtime#68374 (comment) I guess the variable could be set at build time?
Probably here: https://github.com/Elringus/DotNetUMD/blob/release/6.0/src/mono/wasm/wasm.proj#L74 Though, I don't think just setting this var will strip all the evals, as they've mentioned they're using them to generate interop functions.
As I understand, will be fixed once this is done https://github.com/dotnet/runtime/pull/74441
Okay, the deed is done, they merged the PR! Is it possible to switch to the new code?
I'll look into this once the change is available in a shipped .NET, which will probably be .NET 8 (judging by the milestone associated with the PR).