paulbartrum / jurassic

A .NET library to parse and execute JavaScript code.
MIT License
868 stars 121 forks source link

System.ArgumentNullException: Value cannot be null. (Parameter 'value') after update from 3.1.0 to 3.2.2 #207

Closed viceice closed 3 years ago

viceice commented 3 years ago

I'm getting the follwing error since the jurassic update at https://github.com/viceice/dotnet-ts-testing/pull/156

System.ArgumentNullException: Value cannot be null. (Parameter 'value')
   at Jurassic.Compiler.RuntimeScope.SetValueCore(String variableName, Object value, Boolean strictMode, Int32 lineNumber, String sourcePath)
   at setWriter(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at writeFile(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at printSourceFileOrBundle(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at emitJsFileOrBundle(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at emitSourceFileOrBundle(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at forEachEmittedFile(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at emitFiles(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at emitWorker(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at anonymous(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at runWithCancellationToken(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at emit(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at transpileModule(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at transform(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.Call(Object thisObj, Object[] arguments)
   at dotnet_ts_testing.Engines.JurassicJsEngine.Compile(String code) in C:\Users\kriese\projects\gh\viceice\dotnet-ts-testing\Engines\JurassicJsEngine.cs:line 14
   at dotnet_ts_testing.Engines.JsEngine.Test(String test) in C:\Users\kriese\projects\gh\viceice\dotnet-ts-testing\Engines\JsEngine.cs:line 61

current code path of called typescript compiler:

        function setWriter(_writer, _sourceMapGenerator) {
            if (_writer && printerOptions.omitTrailingSemicolon) {
                _writer = ts.getTrailingSemicolonDeferringWriter(_writer);
            }
            writer = _writer; // TODO: GH#18217
            sourceMapGenerator = _sourceMapGenerator;
            sourceMapsDisabled = !writer || !sourceMapGenerator;
        }
        function writeFile(sourceFile, output, sourceMapGenerator) {
            isOwnFileEmit = true;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(sourceFile);
            emitPrologueDirectivesIfNeeded(sourceFile);
            print(0 /* SourceFile */, sourceFile, sourceFile);
            reset();
            writer = previousWriter;
        }
kpreisser commented 3 years ago

Simplified repro:

    var engine = new ScriptEngine();
    engine.Execute(@"

function func(a) {
    function z() { }
}

(function() {
    var x;
    func(x);
})();

");

throws:

System.ArgumentNullException: Value cannot be null. (Parameter 'value')
   at Jurassic.Compiler.RuntimeScope.SetValueCore(String variableName, Object value, Boolean strictMode, Int32 lineNumber, String sourcePath) in C:\Users\developer4\Desktop\Jurassic\jurassic\Jurassic\Compiler\ExecutionContext\RuntimeScope.cs:line 335
   at Jurassic.Compiler.RuntimeScope.SetValue(String variableName, Object value, Int32 lineNumber, String sourcePath) in C:\Users\developer4\Desktop\Jurassic\jurassic\Jurassic\Compiler\ExecutionContext\RuntimeScope.cs:line 306
   at func(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at anonymous(ExecutionContext , Object[] )
   at Jurassic.Library.UserDefinedFunction.CallLateBound(Object thisObject, Object[] argumentValues)
   at Jurassic.Library.FunctionInstance.CallWithStackTrace(String path, String function, Int32 line, Object thisObject, Object[] argumentValues)
   at global(ExecutionContext )
   at Jurassic.Compiler.GlobalOrEvalMethodGenerator.Execute(ScriptEngine engine, RuntimeScope parentScope, Object thisObject)
   at Jurassic.CompiledScript.Execute(ScriptEngine engine)
   at Jurassic.ScriptEngine.Execute(ScriptSource source)
   at Jurassic.ScriptEngine.Execute(String code)
   at JurassicConsoleCore.Program.Main(String[] args)

The issue appears to have been introduced with #185; before that commit, the exception doesn't occur.

paulbartrum commented 3 years ago

Thanks for the bug report; I've published an updated Nuget package (version 3.2.3), it should fix the issue :-)

viceice commented 2 years ago

Works thanks for fast fix.