feat(electron): report V8 cachedData compilation boundaries (#9501)

* feat(electron): report V8 cachedData execution boundaries

analyze-javascript-application treated new vm.Script(source, {cachedData}) and vm.compileFunction(..., {cachedData}) as ordinary source. V8 deserializes previously compiled bytecode for those calls, so an Electron preload wrapper that delegates its whole contextBridge and IPC surface to a .cache/.jsc snapshot appeared to have been fully analyzed with zero exposed APIs.

Record each vm compilation with its inert cache path when the cachedData value traces to a readFileSync/readFile of path syntax, and project a cached-data execution unknown plus a loads edge from the owning source. Compilations without a cache stay recorded as no-cached-data so absence remains distinguishable from an unparsed snapshot. Count cachedData executions in the Electron summary and state the coverage limit in the graph limitations.

* style(cli): wrap the native data type path description

The `inspect-native-data-type` argument description line is 82 columns, over the repository's 80-column `.oxfmtrc.json` limit, so `npm run format:check` fails on main and on every branch merged from it. It came in with #9465 and the following commits to this file did not touch it. Reformat the one call the formatter objects to; no behaviour change.

* style(domain): reformat the pending dynamic-code accumulator field

`npm run format:check` fails on this branch, which is what `Static checks` reports: oxfmt wants the `pendingDynamicCode` union on one line. Applying it is the whole change; no behaviour is touched.

* fix(electron): preserve VM callable and cache source uncertainty

* docs(javascript): specify cached-data compilation boundaries

* fix(electron): exclude disabled caches from recovered boundaries

---------

Co-authored-by: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-11-09 20:16:18 +08:00
1 parent ab1b9e35d0
commit 2c27c2a43b
21 files changed
+982 -4

No files matched your search

@@ -304,6 +304,36 @@ const electron = z
dynamic_member_access: z.boolean().optional(),
}),
),
dynamic_code: z
.array(
z
.strictObject({
...findingContext,
api: z.enum(["vm.Script", "vm.compileFunction"]),
cached_data_status: z.enum(["declared", "absent", "unknown"]),
cached_data: z.union([
z.strictObject({
source_path: z.string(),
source_path_base: z
.enum(["source-directory", "literal-path"])
.optional(),
source_resolution_context: z.enum([
"filesystem-expression",
"module-specifier",
]),
source_expression: z.null(),
}),
z.strictObject({
source_path: z.null(),
source_resolution_context: z.null(),
source_expression: z.string(),
}),
]),
source_text: staticValue,
})
.transform(withRuntime),
)
.optional(),
protocols: z.array(
z
.strictObject({
@@ -322,10 +352,11 @@ const electron = z
.transform(withRuntime),
),
})
.transform(({ call_paths, app_path_changes, ...rest }) => ({
.transform(({ call_paths, app_path_changes, dynamic_code, ...rest }) => ({
...rest,
...(app_path_changes === undefined ? {} : { app_path_changes }),
...(call_paths === undefined ? {} : { call_paths }),
...(dynamic_code === undefined ? {} : { dynamic_code }),
}));
const referenceShape = {
...findingContext,