From e1e2d6d580df1ef5216d857ed56c29036344d628 Mon Sep 17 00:00:00 2001 From: adams85 <31276480+adams85@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:42:40 +0200 Subject: [PATCH] Prevent users from passing arbitrary parser options to Jint (#1831) * Reduce parsing options for end users (replace ParserOptions with Script/ModuleParseOptions in the public API) * Enforce that pre-parsed scripts can be passed to Jint only if they were created using Engine.PrepareScript/PrepareModule * Avoid copying beefy ExecutionContext struct where possible * Propagate ParserOptions via ExecutionContext * Introduce alias for Esprima.Ast.Module --- Directory.Build.props | 1 + Directory.Packages.props | 2 +- Jint.Benchmark/DromaeoBenchmark.cs | 2 +- Jint.Benchmark/EngineComparisonBenchmark.cs | 5 +- Jint.Benchmark/EngineConstructionBenchmark.cs | 9 +- Jint.Benchmark/ObjectAccessBenchmark.cs | 2 +- Jint.Benchmark/ShadowRealmBenchmark.cs | 2 +- Jint.Benchmark/SingleScriptBenchmark.cs | 2 +- Jint.Repl/Program.cs | 6 +- Jint.Tests.CommonScripts/ConcurrencyTest.cs | 8 +- .../ModuleLoaderTests.cs | 20 +- .../ShadowRealmTests.cs | 3 +- Jint.Tests.Test262/State.cs | 2 +- Jint.Tests.Test262/Test262Test.cs | 14 +- .../Runtime/EngineTests.ScriptPreparation.cs | 12 +- Jint.Tests/Runtime/EngineTests.cs | 14 +- Jint.Tests/Runtime/ErrorTests.cs | 16 +- .../Runtime/ParserOptionsPropagationTests.cs | 215 ++++++++++++++++++ Jint/Engine.Ast.cs | 55 ++--- Jint/Engine.Defaults.cs | 18 ++ Jint/Engine.Modules.cs | 2 +- Jint/Engine.cs | 101 ++++---- Jint/HoistingScope.cs | 9 +- Jint/Native/Function/ClassDefinition.cs | 10 +- Jint/Native/Function/EvalFunction.cs | 10 +- Jint/Native/Function/Function.cs | 7 +- .../Function/FunctionInstance.Dynamic.cs | 9 +- Jint/Native/Function/ScriptFunction.cs | 4 +- Jint/Native/Generator/GeneratorInstance.cs | 2 +- Jint/Native/Json/JsonParser.cs | 5 - Jint/Native/RegExp/RegExpConstructor.cs | 3 +- Jint/Native/ShadowRealm/ShadowRealm.cs | 52 +++-- .../ShadowRealm/ShadowRealmPrototype.cs | 9 +- Jint/ParsingOptions.cs | 116 ++++++++++ Jint/PreparationOptions.cs | 51 +++++ Jint/Prepared.cs | 20 ++ Jint/Runtime/Debugger/DebugHandler.cs | 21 +- Jint/Runtime/Environments/ExecutionContext.cs | 5 +- Jint/Runtime/ExceptionHelper.cs | 12 + Jint/Runtime/ExecutionContextStack.cs | 32 ++- Jint/Runtime/Modules/BuilderModule.cs | 2 +- Jint/Runtime/Modules/ModuleBuilder.cs | 48 ++-- Jint/Runtime/Modules/ModuleFactory.cs | 23 +- Jint/Runtime/Modules/SourceTextModule.cs | 14 +- Jint/Runtime/Modules/SyntheticModule.cs | 8 +- 45 files changed, 754 insertions(+), 229 deletions(-) create mode 100644 Jint.Tests/Runtime/ParserOptionsPropagationTests.cs create mode 100644 Jint/Engine.Defaults.cs create mode 100644 Jint/ParsingOptions.cs create mode 100644 Jint/PreparationOptions.cs create mode 100644 Jint/Prepared.cs diff --git a/Directory.Build.props b/Directory.Build.props index ae0709f9b1..8c7ce43660 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -32,6 +32,7 @@ + diff --git a/Directory.Packages.props b/Directory.Packages.props index 70e4f1ed13..60faeca213 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,7 @@ - + diff --git a/Jint.Benchmark/DromaeoBenchmark.cs b/Jint.Benchmark/DromaeoBenchmark.cs index 295df63160..d569e64795 100644 --- a/Jint.Benchmark/DromaeoBenchmark.cs +++ b/Jint.Benchmark/DromaeoBenchmark.cs @@ -15,7 +15,7 @@ public class DromaeoBenchmark {"dromaeo-string-base64", null} }; - private readonly Dictionary _prepared = new(); + private readonly Dictionary> _prepared = new(); private Engine engine; diff --git a/Jint.Benchmark/EngineComparisonBenchmark.cs b/Jint.Benchmark/EngineComparisonBenchmark.cs index 9dba692148..4499c8b2e9 100644 --- a/Jint.Benchmark/EngineComparisonBenchmark.cs +++ b/Jint.Benchmark/EngineComparisonBenchmark.cs @@ -12,7 +12,7 @@ namespace Jint.Benchmark; [BenchmarkCategory("EngineComparison")] public class EngineComparisonBenchmark { - private static readonly Dictionary _parsedScripts = new(); + private static readonly Dictionary> _parsedScripts = new(); private static readonly Dictionary _files = new() { @@ -38,7 +38,6 @@ public class EngineComparisonBenchmark [GlobalSetup] public void Setup() { - var parser = new Parser(); foreach (var fileName in _files.Keys.ToList()) { var script = File.ReadAllText($"Scripts/{fileName}.js"); @@ -47,7 +46,7 @@ public void Setup() script = _dromaeoHelpers + Environment.NewLine + Environment.NewLine + script; } _files[fileName] = script; - _parsedScripts[fileName] = parser.ParseScript(script, strict: true); + _parsedScripts[fileName] = Engine.PrepareScript(script, strict: true); } } diff --git a/Jint.Benchmark/EngineConstructionBenchmark.cs b/Jint.Benchmark/EngineConstructionBenchmark.cs index 0b7ce7937a..2e103d69d1 100644 --- a/Jint.Benchmark/EngineConstructionBenchmark.cs +++ b/Jint.Benchmark/EngineConstructionBenchmark.cs @@ -6,15 +6,14 @@ namespace Jint.Benchmark; [MemoryDiagnoser] public class EngineConstructionBenchmark { - private Script _program; - private Script _simple; + private Prepared