DataDog / datadog-static-analyzer

Datadog Static Analyzer
https://docs.datadoghq.com/static_analysis/
Apache License 2.0
100 stars 12 forks source link

[STAL-1960] Add functionality to configure a v8 isolate's default context #404

Closed jasonforal closed 3 months ago

jasonforal commented 3 months ago

What problem are you trying to solve?

TL;DR console.log in our scoped_execute function currently resolves to deno_core's console, not our custom ddsa console.

--

In https://github.com/DataDog/datadog-static-analyzer/pull/398, we introduced scoped_execute, which creates a new v8::Context to execute a v8::Script in. The global proxy object for this new v8 context is constructed from the v8::ObjectTemplate of the v8 isolate "default" context (which is its baseline current context).

In order to re-use a v8::Persistent global object (for ddsa-specific values) across executions, we set the prototype of the new v8 context's global object to our v8::Persistent object.

Because of how the JavaScript prototype chain works, resolving a value on globalThis will first check the v8 context's immediate global object, and then failing a match, walk up the prototype chain.

In practice, because deno_core injects its own globalThis.console, this means when we run a script through scoped_execute, calls to console are caught by the console deno_core injected.

What is your solution?

Because deno_core doesn't provide hooks to configure the values it sets on the default v8 context global object, we introduce a function that allows the caller to provide a function that can mutate the default v8 context. This runs after deno_core has finished executing its own default context mutation, so we can, e.g. remove console from the global proxy object so it will resolve to our "console" (via the prototype chain).

Effectively what we're doing is creating a v8 isolate, mutating its base context, and then serializing it into a "snapshot" (see https://v8docs.nodesource.com/node-20.3/d6/d77/classv8_1_1_snapshot_creator.html).

Then we create the final v8 isolate based on this snapshot, which means any new v8::Context we create will use the snapshot's default v8 context as a template.

Alternatives considered

What the reviewer should know

jasonforal commented 3 months ago

(Force pushed to rebase due to chained PRs requiring this PR to land -- no code changes from original PR)

jasonforal commented 3 months ago

Force pushing to resolve merge conflict, then merging

Rebase can be verified here: https://github.com/DataDog/datadog-static-analyzer/compare/1148a72ecfebf9c75a944944ca197ee983b838bb..cd772888c438f1690eb8b01598f4451cc3d6afb5