fix(javascript): attribute service workers to intact platform paths

Check the complete navigator.serviceWorker.register identity through the shared
ambient-write owner, including replaced methods and aliased receiver mutations.
Reuse the module URL reader for intact registrations while preserving unknown
document-relative strings. Cover the unresolved review case and the CLI graph.

Refs #3841

Co-authored-by: Chandan Chaudhary <chandankkumar156@gmail.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
This commit is contained in:
committed 2026-10-16 06:06:06 +08:00
1 parent 880b3a510b
commit 396b89c5e2
4 files changed
+157 -19

No files matched your search

@@ -289,27 +289,28 @@ export function* indexJavaScriptAmbientWritesSteps(
}
/**
* Recognize an ambient name or direct global-object property without a visible
* Recognize an ambient property path, optionally through a global object, without a visible
* source-local overwrite. This is a syntax-local identity fact, not proof that
* the runtime's globals have never been patched by other code.
*/
export const isUnmodifiedGlobalReference = (
callee: t.Node,
state: JavaScriptSemanticAnalysisState,
name: string,
name: string | readonly [string, ...string[]],
): boolean => {
const node = unwrapJavaScriptExpression(callee).node;
if (state.ambientWrites.covers(["global", name])) return false;
if (isUnshadowedGlobal(node, state, name)) return true;
if (
!t.isMemberExpression(node) ||
semanticStaticPropertyKey(node.property, node.computed) !== name
)
return false;
const root = unwrapJavaScriptExpression(node.object).node;
const path: readonly [string, ...string[]] =
typeof name === "string" ? [name] : name;
if (state.ambientWrites.covers(["global", ...path])) return false;
const { root, members } = electronMemberPath(callee);
const matches = (expected: readonly string[]) =>
members.length === expected.length &&
members.every((key, index) => key === expected[index]);
if (isUnshadowedGlobal(root, state, path[0]) && matches(path.slice(1)))
return true;
const namespace = globalObjectName(root, state);
return (
namespace !== undefined &&
matches(path) &&
!state.ambientWrites.covers(["global", namespace])
);
};