@keithadler/frostjs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +568 -0
- package/dist/baseline.d.ts +18 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +56 -0
- package/dist/baseline.js.map +1 -0
- package/dist/changed.d.ts +15 -0
- package/dist/changed.d.ts.map +1 -0
- package/dist/changed.js +93 -0
- package/dist/changed.js.map +1 -0
- package/dist/cli/args.d.ts +37 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +200 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +8 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/run.d.ts +9 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +404 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/discover/index.d.ts +15 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +70 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/eslint.d.ts +103 -0
- package/dist/eslint.d.ts.map +1 -0
- package/dist/eslint.js +111 -0
- package/dist/eslint.js.map +1 -0
- package/dist/extract/annotations.d.ts +5 -0
- package/dist/extract/annotations.d.ts.map +1 -0
- package/dist/extract/annotations.js +5 -0
- package/dist/extract/annotations.js.map +1 -0
- package/dist/extract/ast.d.ts +45 -0
- package/dist/extract/ast.d.ts.map +1 -0
- package/dist/extract/ast.js +60 -0
- package/dist/extract/ast.js.map +1 -0
- package/dist/extract/capability.d.ts +22 -0
- package/dist/extract/capability.d.ts.map +1 -0
- package/dist/extract/capability.js +2 -0
- package/dist/extract/capability.js.map +1 -0
- package/dist/extract/html.d.ts +15 -0
- package/dist/extract/html.d.ts.map +1 -0
- package/dist/extract/html.js +69 -0
- package/dist/extract/html.js.map +1 -0
- package/dist/extract/index.d.ts +9 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +95 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/recognizers/codegen.d.ts +10 -0
- package/dist/extract/recognizers/codegen.d.ts.map +1 -0
- package/dist/extract/recognizers/codegen.js +39 -0
- package/dist/extract/recognizers/codegen.js.map +1 -0
- package/dist/extract/recognizers/dom-escape.d.ts +11 -0
- package/dist/extract/recognizers/dom-escape.d.ts.map +1 -0
- package/dist/extract/recognizers/dom-escape.js +58 -0
- package/dist/extract/recognizers/dom-escape.js.map +1 -0
- package/dist/extract/recognizers/globals.d.ts +9 -0
- package/dist/extract/recognizers/globals.d.ts.map +1 -0
- package/dist/extract/recognizers/globals.js +121 -0
- package/dist/extract/recognizers/globals.js.map +1 -0
- package/dist/extract/recognizers/identity.d.ts +10 -0
- package/dist/extract/recognizers/identity.d.ts.map +1 -0
- package/dist/extract/recognizers/identity.js +79 -0
- package/dist/extract/recognizers/identity.js.map +1 -0
- package/dist/extract/recognizers/navigation.d.ts +12 -0
- package/dist/extract/recognizers/navigation.d.ts.map +1 -0
- package/dist/extract/recognizers/navigation.js +110 -0
- package/dist/extract/recognizers/navigation.js.map +1 -0
- package/dist/extract/recognizers/network.d.ts +11 -0
- package/dist/extract/recognizers/network.d.ts.map +1 -0
- package/dist/extract/recognizers/network.js +41 -0
- package/dist/extract/recognizers/network.js.map +1 -0
- package/dist/extract/recognizers/resolve.d.ts +37 -0
- package/dist/extract/recognizers/resolve.d.ts.map +1 -0
- package/dist/extract/recognizers/resolve.js +72 -0
- package/dist/extract/recognizers/resolve.js.map +1 -0
- package/dist/extract/recognizers/storage.d.ts +9 -0
- package/dist/extract/recognizers/storage.d.ts.map +1 -0
- package/dist/extract/recognizers/storage.js +37 -0
- package/dist/extract/recognizers/storage.js.map +1 -0
- package/dist/extract/recognizers/types.d.ts +38 -0
- package/dist/extract/recognizers/types.d.ts.map +1 -0
- package/dist/extract/recognizers/types.js +25 -0
- package/dist/extract/recognizers/types.js.map +1 -0
- package/dist/extract/recognizers/worker.d.ts +11 -0
- package/dist/extract/recognizers/worker.d.ts.map +1 -0
- package/dist/extract/recognizers/worker.js +41 -0
- package/dist/extract/recognizers/worker.js.map +1 -0
- package/dist/extract/scope.d.ts +23 -0
- package/dist/extract/scope.d.ts.map +1 -0
- package/dist/extract/scope.js +299 -0
- package/dist/extract/scope.js.map +1 -0
- package/dist/extract/suppress.d.ts +21 -0
- package/dist/extract/suppress.d.ts.map +1 -0
- package/dist/extract/suppress.js +42 -0
- package/dist/extract/suppress.js.map +1 -0
- package/dist/extract/target.d.ts +34 -0
- package/dist/extract/target.d.ts.map +1 -0
- package/dist/extract/target.js +81 -0
- package/dist/extract/target.js.map +1 -0
- package/dist/extract/typescript.d.ts +12 -0
- package/dist/extract/typescript.d.ts.map +1 -0
- package/dist/extract/typescript.js +56 -0
- package/dist/extract/typescript.js.map +1 -0
- package/dist/extract/walk.d.ts +14 -0
- package/dist/extract/walk.d.ts.map +1 -0
- package/dist/extract/walk.js +70 -0
- package/dist/extract/walk.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +10 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +79 -0
- package/dist/init.js.map +1 -0
- package/dist/policy/compile.d.ts +56 -0
- package/dist/policy/compile.d.ts.map +1 -0
- package/dist/policy/compile.js +78 -0
- package/dist/policy/compile.js.map +1 -0
- package/dist/policy/config.d.ts +18 -0
- package/dist/policy/config.d.ts.map +1 -0
- package/dist/policy/config.js +70 -0
- package/dist/policy/config.js.map +1 -0
- package/dist/policy/csp.d.ts +19 -0
- package/dist/policy/csp.d.ts.map +1 -0
- package/dist/policy/csp.js +47 -0
- package/dist/policy/csp.js.map +1 -0
- package/dist/policy/glob.d.ts +12 -0
- package/dist/policy/glob.d.ts.map +1 -0
- package/dist/policy/glob.js +63 -0
- package/dist/policy/glob.js.map +1 -0
- package/dist/policy/index.d.ts +47 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +34 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/parse.d.ts +51 -0
- package/dist/policy/parse.d.ts.map +1 -0
- package/dist/policy/parse.js +352 -0
- package/dist/policy/parse.js.map +1 -0
- package/dist/policy/vocabulary.d.ts +15 -0
- package/dist/policy/vocabulary.d.ts.map +1 -0
- package/dist/policy/vocabulary.js +99 -0
- package/dist/policy/vocabulary.js.map +1 -0
- package/dist/registry.d.ts +45 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +85 -0
- package/dist/registry.js.map +1 -0
- package/dist/report/github.d.ts +10 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +31 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/json.d.ts +44 -0
- package/dist/report/json.d.ts.map +1 -0
- package/dist/report/json.js +40 -0
- package/dist/report/json.js.map +1 -0
- package/dist/report/sarif.d.ts +10 -0
- package/dist/report/sarif.d.ts.map +1 -0
- package/dist/report/sarif.js +64 -0
- package/dist/report/sarif.js.map +1 -0
- package/dist/report/summary.d.ts +9 -0
- package/dist/report/summary.d.ts.map +1 -0
- package/dist/report/summary.js +67 -0
- package/dist/report/summary.js.map +1 -0
- package/dist/report/text.d.ts +37 -0
- package/dist/report/text.d.ts.map +1 -0
- package/dist/report/text.js +81 -0
- package/dist/report/text.js.map +1 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +131 -0
- package/dist/sync.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { callArgs, match, plain, stringValue } from "./types.js";
|
|
2
|
+
import { asNamedGlobal, memberName } from "./resolve.js";
|
|
3
|
+
/** Properties whose assignment parses HTML. */
|
|
4
|
+
const HTML_SINKS = new Set(["innerHTML", "outerHTML", "srcdoc"]);
|
|
5
|
+
/** Methods whose call parses HTML. */
|
|
6
|
+
const HTML_METHODS = new Set(["insertAdjacentHTML", "createContextualFragment"]);
|
|
7
|
+
/** Intrinsic JSX elements, and createElement tag names, that run code. */
|
|
8
|
+
const CODE_ELEMENTS = new Map([
|
|
9
|
+
["script", "dom-escape.script"],
|
|
10
|
+
["iframe", "dom-escape.iframe"],
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* DOM escape hatches: anything that turns a string into markup or creates
|
|
14
|
+
* an element that runs code. The object is not checked - `el.innerHTML = x`
|
|
15
|
+
* is injection whatever `el` is - but only writes and calls count; reading
|
|
16
|
+
* innerHTML is not injection. In JSX, `dangerouslySetInnerHTML` and
|
|
17
|
+
* `srcdoc` attributes and intrinsic `<script>` / `<iframe>` elements count;
|
|
18
|
+
* component names do not.
|
|
19
|
+
*/
|
|
20
|
+
export const domEscape = ({ node, ancestors, binding }) => {
|
|
21
|
+
if (binding)
|
|
22
|
+
return null;
|
|
23
|
+
const n = node;
|
|
24
|
+
if (n.type === "JSXAttribute") {
|
|
25
|
+
const name = n["name"];
|
|
26
|
+
const attr = name.type === "JSXIdentifier" ? name["name"] : null;
|
|
27
|
+
return attr === "dangerouslySetInnerHTML" || attr === "srcdoc" ? plain("dom-escape.html", node) : null;
|
|
28
|
+
}
|
|
29
|
+
if (n.type === "JSXOpeningElement") {
|
|
30
|
+
const name = n["name"];
|
|
31
|
+
const cap = name.type === "JSXIdentifier" ? CODE_ELEMENTS.get(name["name"]) : undefined;
|
|
32
|
+
return cap ? plain(cap, node) : null;
|
|
33
|
+
}
|
|
34
|
+
if (n.type !== "MemberExpression")
|
|
35
|
+
return null;
|
|
36
|
+
const prop = memberName(n);
|
|
37
|
+
if (prop === null)
|
|
38
|
+
return null;
|
|
39
|
+
const parent = ancestors[0];
|
|
40
|
+
if (!parent)
|
|
41
|
+
return null;
|
|
42
|
+
if (HTML_SINKS.has(prop)) {
|
|
43
|
+
const assigned = parent.type === "AssignmentExpression" && parent["left"] === node;
|
|
44
|
+
return assigned ? plain("dom-escape.html", parent) : null;
|
|
45
|
+
}
|
|
46
|
+
const args = callArgs(node, parent);
|
|
47
|
+
if (!args)
|
|
48
|
+
return null;
|
|
49
|
+
if (HTML_METHODS.has(prop))
|
|
50
|
+
return plain("dom-escape.html", node);
|
|
51
|
+
if (prop === "createElement") {
|
|
52
|
+
const r = asNamedGlobal(n["object"], "document");
|
|
53
|
+
const cap = r ? CODE_ELEMENTS.get(stringValue(args[0])?.toLowerCase() ?? "") : undefined;
|
|
54
|
+
return r && cap ? match(cap, r, node) : null;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=dom-escape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-escape.js","sourceRoot":"","sources":["../../../src/extract/recognizers/dom-escape.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzD,+CAA+C;AAC/C,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEtF,sCAAsC;AACtC,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,0BAA0B,CAAC,CAAC,CAAC;AAEtG,0EAA0E;AAC1E,MAAM,aAAa,GAAgC,IAAI,GAAG,CAAC;IACzD,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IAC/B,CAAC,QAAQ,EAAE,mBAAmB,CAAC;CAChC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAe,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE;IACpE,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,CAAC,GAAG,IAAe,CAAC;IAE1B,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAY,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAE,IAAI,CAAC,MAAM,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7E,OAAO,IAAI,KAAK,yBAAyB,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzG,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAY,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClG,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAwB,CAAC;IACnD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,KAAK,sBAAsB,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;QACnF,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAClE,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAY,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzF,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Recognizer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Mutation of shared state: properties added to the global object, and
|
|
4
|
+
* built-ins or their prototypes changed. Reads are not reported, and neither
|
|
5
|
+
* are window's own event-handler properties (`window.onload = f`), which
|
|
6
|
+
* install a handler rather than a global.
|
|
7
|
+
*/
|
|
8
|
+
export declare const globals: Recognizer;
|
|
9
|
+
//# sourceMappingURL=globals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../../src/extract/recognizers/globals.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,UAAU,EAAiB,MAAM,YAAY,CAAC;AA0E7E;;;;;GAKG;AACH,eAAO,MAAM,OAAO,EAAE,UAkCrB,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { callArgs, match } from "./types.js";
|
|
2
|
+
import { asGlobalObject, isIdentifier, memberName } from "./resolve.js";
|
|
3
|
+
/** Built-in constructors and namespaces whose mutation affects every script on the page. */
|
|
4
|
+
const BUILTINS = new Set([
|
|
5
|
+
"Object",
|
|
6
|
+
"Array",
|
|
7
|
+
"String",
|
|
8
|
+
"Number",
|
|
9
|
+
"Boolean",
|
|
10
|
+
"Function",
|
|
11
|
+
"Symbol",
|
|
12
|
+
"BigInt",
|
|
13
|
+
"Date",
|
|
14
|
+
"RegExp",
|
|
15
|
+
"Error",
|
|
16
|
+
"Promise",
|
|
17
|
+
"Map",
|
|
18
|
+
"Set",
|
|
19
|
+
"WeakMap",
|
|
20
|
+
"WeakSet",
|
|
21
|
+
"WeakRef",
|
|
22
|
+
"Math",
|
|
23
|
+
"JSON",
|
|
24
|
+
"Reflect",
|
|
25
|
+
"Proxy",
|
|
26
|
+
"Intl",
|
|
27
|
+
"ArrayBuffer",
|
|
28
|
+
"DataView",
|
|
29
|
+
"Uint8Array",
|
|
30
|
+
"Int8Array",
|
|
31
|
+
"Uint16Array",
|
|
32
|
+
"Int16Array",
|
|
33
|
+
"Uint32Array",
|
|
34
|
+
"Int32Array",
|
|
35
|
+
"Float32Array",
|
|
36
|
+
"Float64Array",
|
|
37
|
+
"Uint8ClampedArray",
|
|
38
|
+
"EventTarget",
|
|
39
|
+
"Event",
|
|
40
|
+
"Node",
|
|
41
|
+
"Element",
|
|
42
|
+
"HTMLElement",
|
|
43
|
+
"Document",
|
|
44
|
+
"Window",
|
|
45
|
+
"Text",
|
|
46
|
+
"CharacterData",
|
|
47
|
+
"DocumentFragment",
|
|
48
|
+
"ShadowRoot",
|
|
49
|
+
"HTMLCollection",
|
|
50
|
+
"NodeList",
|
|
51
|
+
"Navigator",
|
|
52
|
+
"Storage",
|
|
53
|
+
"Location",
|
|
54
|
+
"History",
|
|
55
|
+
"XMLHttpRequest",
|
|
56
|
+
"Response",
|
|
57
|
+
"Request",
|
|
58
|
+
"Headers",
|
|
59
|
+
"URL",
|
|
60
|
+
]);
|
|
61
|
+
const MUTATORS = new Set(["defineProperty", "defineProperties", "assign", "setPrototypeOf"]);
|
|
62
|
+
/** `<Builtin>` or `<Builtin>.prototype`, as a resolved reference. */
|
|
63
|
+
function asBuiltinSurface(n) {
|
|
64
|
+
if (isIdentifier(n) && BUILTINS.has(n.name))
|
|
65
|
+
return { confidence: "certain", via: n };
|
|
66
|
+
if (n.type === "MemberExpression" && memberName(n) === "prototype") {
|
|
67
|
+
const obj = n["object"];
|
|
68
|
+
if (isIdentifier(obj) && BUILTINS.has(obj.name))
|
|
69
|
+
return { confidence: "certain", via: obj };
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Mutation of shared state: properties added to the global object, and
|
|
75
|
+
* built-ins or their prototypes changed. Reads are not reported, and neither
|
|
76
|
+
* are window's own event-handler properties (`window.onload = f`), which
|
|
77
|
+
* install a handler rather than a global.
|
|
78
|
+
*/
|
|
79
|
+
export const globals = ({ node, ancestors, binding }) => {
|
|
80
|
+
if (binding)
|
|
81
|
+
return null;
|
|
82
|
+
const n = node;
|
|
83
|
+
const parent = ancestors[0];
|
|
84
|
+
if (!parent)
|
|
85
|
+
return null;
|
|
86
|
+
// window.x = v, Array.prototype.x = v, Array.from = v
|
|
87
|
+
if (parent.type === "AssignmentExpression" && parent["left"] === node && n.type === "MemberExpression") {
|
|
88
|
+
const prop = memberName(n);
|
|
89
|
+
const obj = n["object"];
|
|
90
|
+
const g = asGlobalObject(obj);
|
|
91
|
+
if (g) {
|
|
92
|
+
if (prop !== null && (prop === "location" || prop.startsWith("on")))
|
|
93
|
+
return null;
|
|
94
|
+
return match("globals.window", g, parent);
|
|
95
|
+
}
|
|
96
|
+
if (prop === "prototype")
|
|
97
|
+
return null; // Foo.prototype = {...} replaces a whole prototype; not a mutation of a built-in
|
|
98
|
+
const b = asBuiltinSurface(obj);
|
|
99
|
+
if (b)
|
|
100
|
+
return match("globals.prototype", b, parent);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
// Object.defineProperty(window, ...), Object.assign(Array.prototype, ...)
|
|
104
|
+
const args = callArgs(node, parent);
|
|
105
|
+
if (args && n.type === "MemberExpression") {
|
|
106
|
+
const prop = memberName(n);
|
|
107
|
+
if (prop === null || !MUTATORS.has(prop) || !isIdentifier(n["object"], "Object"))
|
|
108
|
+
return null;
|
|
109
|
+
const first = args[0];
|
|
110
|
+
if (!first)
|
|
111
|
+
return null;
|
|
112
|
+
const g = asGlobalObject(first);
|
|
113
|
+
if (g)
|
|
114
|
+
return match("globals.window", g, node);
|
|
115
|
+
const b = asBuiltinSurface(first);
|
|
116
|
+
if (b)
|
|
117
|
+
return match("globals.prototype", b, node);
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=globals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../../../src/extract/recognizers/globals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Recognizer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Identity and fingerprinting surfaces reached through `navigator`, plus
|
|
4
|
+
* the legacy clipboard path through document.execCommand. Canvas and audio
|
|
5
|
+
* fingerprinting are deliberately not recognized: every charting and 3D
|
|
6
|
+
* library draws to canvases, and no static signature separates that from
|
|
7
|
+
* fingerprinting without false positives.
|
|
8
|
+
*/
|
|
9
|
+
export declare const identity: Recognizer;
|
|
10
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/extract/recognizers/identity.ts"],"names":[],"mappings":"AACA,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AA4B3E;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,EAAE,UA0CtB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { callArgs, match, stringValue } from "./types.js";
|
|
2
|
+
import { asNamedGlobal, memberName } from "./resolve.js";
|
|
3
|
+
/** navigator members that identify the device, user, or their surroundings. */
|
|
4
|
+
const NAVIGATOR = new Map([
|
|
5
|
+
["userAgent", "identity.device"],
|
|
6
|
+
["userAgentData", "identity.device"],
|
|
7
|
+
["platform", "identity.device"],
|
|
8
|
+
["vendor", "identity.device"],
|
|
9
|
+
["appVersion", "identity.device"],
|
|
10
|
+
["appName", "identity.device"],
|
|
11
|
+
["oscpu", "identity.device"],
|
|
12
|
+
["hardwareConcurrency", "identity.device"],
|
|
13
|
+
["deviceMemory", "identity.device"],
|
|
14
|
+
["plugins", "identity.device"],
|
|
15
|
+
["mimeTypes", "identity.device"],
|
|
16
|
+
["geolocation", "identity.geolocation"],
|
|
17
|
+
["mediaDevices", "identity.media"],
|
|
18
|
+
["getUserMedia", "identity.media"],
|
|
19
|
+
["webkitGetUserMedia", "identity.media"],
|
|
20
|
+
["mozGetUserMedia", "identity.media"],
|
|
21
|
+
["clipboard", "identity.clipboard"],
|
|
22
|
+
["credentials", "identity.credentials"],
|
|
23
|
+
["permissions", "identity.permissions"],
|
|
24
|
+
]);
|
|
25
|
+
const CLIPBOARD_COMMANDS = new Set(["copy", "cut", "paste"]);
|
|
26
|
+
/**
|
|
27
|
+
* Identity and fingerprinting surfaces reached through `navigator`, plus
|
|
28
|
+
* the legacy clipboard path through document.execCommand. Canvas and audio
|
|
29
|
+
* fingerprinting are deliberately not recognized: every charting and 3D
|
|
30
|
+
* library draws to canvases, and no static signature separates that from
|
|
31
|
+
* fingerprinting without false positives.
|
|
32
|
+
*/
|
|
33
|
+
export const identity = ({ node, ancestors, binding }) => {
|
|
34
|
+
if (binding)
|
|
35
|
+
return null;
|
|
36
|
+
const n = node;
|
|
37
|
+
// const { userAgent, clipboard } = navigator
|
|
38
|
+
if (n.type === "VariableDeclarator" || n.type === "AssignmentExpression") {
|
|
39
|
+
const pattern = (n.type === "VariableDeclarator" ? n["id"] : n["left"]);
|
|
40
|
+
const source = (n.type === "VariableDeclarator" ? n["init"] : n["right"]);
|
|
41
|
+
if (!source || pattern.type !== "ObjectPattern")
|
|
42
|
+
return null;
|
|
43
|
+
const r = asNamedGlobal(source, "navigator");
|
|
44
|
+
if (!r)
|
|
45
|
+
return null;
|
|
46
|
+
for (const p of pattern["properties"]) {
|
|
47
|
+
if (p.type !== "Property" || p["computed"] === true)
|
|
48
|
+
continue;
|
|
49
|
+
const key = p["key"];
|
|
50
|
+
const name = key.type === "Identifier" ? key["name"] : key.type === "Literal" ? String(key["value"]) : null;
|
|
51
|
+
const cap = name === null ? undefined : NAVIGATOR.get(name);
|
|
52
|
+
// One match per declarator is enough to name the capability; report the first.
|
|
53
|
+
if (cap)
|
|
54
|
+
return match(cap, r, node);
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
if (n.type !== "MemberExpression")
|
|
59
|
+
return null;
|
|
60
|
+
const prop = memberName(n);
|
|
61
|
+
if (prop === null)
|
|
62
|
+
return null;
|
|
63
|
+
const obj = n["object"];
|
|
64
|
+
const cap = NAVIGATOR.get(prop);
|
|
65
|
+
if (cap) {
|
|
66
|
+
const r = asNamedGlobal(obj, "navigator");
|
|
67
|
+
return r ? match(cap, r, node) : null;
|
|
68
|
+
}
|
|
69
|
+
if (prop === "execCommand") {
|
|
70
|
+
const args = callArgs(node, ancestors[0]);
|
|
71
|
+
const cmd = stringValue(args?.[0])?.toLowerCase();
|
|
72
|
+
if (cmd === undefined || !CLIPBOARD_COMMANDS.has(cmd))
|
|
73
|
+
return null;
|
|
74
|
+
const r = asNamedGlobal(obj, "document");
|
|
75
|
+
return r ? match("identity.clipboard", r, node) : null;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/extract/recognizers/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Recognizer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Moving the user or another window: assignment to `location` or its
|
|
4
|
+
* navigating members (reads and `hash` are not navigation),
|
|
5
|
+
* `location.assign/replace/reload`, `window.open`, the history methods, and
|
|
6
|
+
* `postMessage` when the receiver is another window (parent, top, opener,
|
|
7
|
+
* contentWindow), a string origin is given, or an options object names
|
|
8
|
+
* targetOrigin. Worker and port postMessage, including the
|
|
9
|
+
* `{ transfer: [...] }` options form, stay quiet.
|
|
10
|
+
*/
|
|
11
|
+
export declare const navigation: Recognizer;
|
|
12
|
+
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/extract/recognizers/navigation.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,UAAU,EAAiB,MAAM,YAAY,CAAC;AAkC7E;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,EAAE,UAkExB,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { callArgs, match } from "./types.js";
|
|
2
|
+
import { asGlobalObject, asNamedGlobal, isIdentifier, memberName } from "./resolve.js";
|
|
3
|
+
import { resolveTargetOf, SAME_ORIGIN } from "../target.js";
|
|
4
|
+
/** location members whose assignment navigates. `hash` stays on the document and is left out. */
|
|
5
|
+
const LOCATION_WRITES = new Set([
|
|
6
|
+
"href",
|
|
7
|
+
"search",
|
|
8
|
+
"pathname",
|
|
9
|
+
"protocol",
|
|
10
|
+
"host",
|
|
11
|
+
"hostname",
|
|
12
|
+
"port",
|
|
13
|
+
]);
|
|
14
|
+
const LOCATION_CALLS = new Set(["assign", "replace", "reload"]);
|
|
15
|
+
const HISTORY_CALLS = new Set(["pushState", "replaceState", "back", "forward", "go"]);
|
|
16
|
+
/** Receivers that are some other window. */
|
|
17
|
+
const WINDOW_RECEIVERS = new Set(["parent", "top", "opener", "contentWindow"]);
|
|
18
|
+
/** `location`, `window.location`, `document.location`. */
|
|
19
|
+
function asLocation(n) {
|
|
20
|
+
if (isIdentifier(n, "location"))
|
|
21
|
+
return { confidence: "certain", via: n };
|
|
22
|
+
if (n.type === "MemberExpression" && memberName(n) === "location") {
|
|
23
|
+
const obj = n["object"];
|
|
24
|
+
return asGlobalObject(obj) ?? asNamedGlobal(obj, "document");
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
/** A window-to-window origin argument: "*" stays "*", anything else resolves like a URL. */
|
|
29
|
+
function originTarget(origin) {
|
|
30
|
+
return origin.type === "Literal" && origin["value"] === "*" ? "*" : resolveTargetOf(origin);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Moving the user or another window: assignment to `location` or its
|
|
34
|
+
* navigating members (reads and `hash` are not navigation),
|
|
35
|
+
* `location.assign/replace/reload`, `window.open`, the history methods, and
|
|
36
|
+
* `postMessage` when the receiver is another window (parent, top, opener,
|
|
37
|
+
* contentWindow), a string origin is given, or an options object names
|
|
38
|
+
* targetOrigin. Worker and port postMessage, including the
|
|
39
|
+
* `{ transfer: [...] }` options form, stay quiet.
|
|
40
|
+
*/
|
|
41
|
+
export const navigation = ({ node, ancestors, binding }) => {
|
|
42
|
+
if (binding)
|
|
43
|
+
return null;
|
|
44
|
+
const n = node;
|
|
45
|
+
const parent = ancestors[0];
|
|
46
|
+
if (!parent)
|
|
47
|
+
return null;
|
|
48
|
+
const assigned = parent.type === "AssignmentExpression" && parent["left"] === node;
|
|
49
|
+
const assignedTarget = () => resolveTargetOf(parent["right"]);
|
|
50
|
+
const args = callArgs(node, parent);
|
|
51
|
+
if (assigned) {
|
|
52
|
+
const loc = asLocation(n);
|
|
53
|
+
if (loc)
|
|
54
|
+
return match("navigation.location", loc, parent, assignedTarget());
|
|
55
|
+
}
|
|
56
|
+
if (n.type !== "MemberExpression")
|
|
57
|
+
return null;
|
|
58
|
+
const prop = memberName(n);
|
|
59
|
+
if (prop === null)
|
|
60
|
+
return null;
|
|
61
|
+
const obj = n["object"];
|
|
62
|
+
if (assigned && LOCATION_WRITES.has(prop)) {
|
|
63
|
+
const loc = asLocation(obj);
|
|
64
|
+
if (loc)
|
|
65
|
+
return match("navigation.location", loc, parent, assignedTarget());
|
|
66
|
+
}
|
|
67
|
+
if (!args)
|
|
68
|
+
return null;
|
|
69
|
+
if (LOCATION_CALLS.has(prop)) {
|
|
70
|
+
const loc = asLocation(obj);
|
|
71
|
+
if (loc)
|
|
72
|
+
return match("navigation.location", loc, node, prop === "reload" ? SAME_ORIGIN : resolveTargetOf(args[0]));
|
|
73
|
+
}
|
|
74
|
+
if (prop === "open") {
|
|
75
|
+
const r = asGlobalObject(obj);
|
|
76
|
+
if (r)
|
|
77
|
+
return match("navigation.open", r, node, resolveTargetOf(args[0]));
|
|
78
|
+
}
|
|
79
|
+
if (HISTORY_CALLS.has(prop)) {
|
|
80
|
+
const r = asNamedGlobal(obj, "history");
|
|
81
|
+
if (r)
|
|
82
|
+
return match("navigation.history", r, node);
|
|
83
|
+
}
|
|
84
|
+
if (prop === "postMessage") {
|
|
85
|
+
const receiver = isIdentifier(obj) ? obj.name : memberName(obj);
|
|
86
|
+
const origin = args[1];
|
|
87
|
+
const originIsString = origin !== undefined &&
|
|
88
|
+
(origin.type === "Literal" ? typeof origin["value"] === "string" : origin.type === "TemplateLiteral");
|
|
89
|
+
// Workers take an options object too ({ transfer }); only a targetOrigin key makes it a window message.
|
|
90
|
+
const originIsOptions = origin?.type === "ObjectExpression" &&
|
|
91
|
+
origin["properties"].some((p) => {
|
|
92
|
+
const key = p["key"];
|
|
93
|
+
return (p.type === "Property" &&
|
|
94
|
+
p["computed"] !== true &&
|
|
95
|
+
(key?.["name"] === "targetOrigin" || key?.["value"] === "targetOrigin"));
|
|
96
|
+
});
|
|
97
|
+
if ((receiver !== null && WINDOW_RECEIVERS.has(receiver)) || originIsString || originIsOptions) {
|
|
98
|
+
const via = isIdentifier(obj) && WINDOW_RECEIVERS.has(obj.name) ? obj : null;
|
|
99
|
+
return {
|
|
100
|
+
capability: "navigation.postmessage",
|
|
101
|
+
target: originIsString ? originTarget(origin) : null,
|
|
102
|
+
confidence: "certain",
|
|
103
|
+
via,
|
|
104
|
+
node,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../src/extract/recognizers/navigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Recognizer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ways code reaches another host: fetch, XMLHttpRequest, WebSocket,
|
|
4
|
+
* EventSource, navigator.sendBeacon, and dynamic import() of an absolute
|
|
5
|
+
* URL or an expression whose destination cannot be fixed. import() of a
|
|
6
|
+
* relative path (code splitting) or a bare specifier ("lodash", "node:fs")
|
|
7
|
+
* resolves through the bundler or import map, not the network, and is not
|
|
8
|
+
* reported.
|
|
9
|
+
*/
|
|
10
|
+
export declare const network: Recognizer;
|
|
11
|
+
//# sourceMappingURL=network.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../../src/extract/recognizers/network.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAarE;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,UAoBrB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { callArgs, match, plain } from "./types.js";
|
|
2
|
+
import { asGlobalIn, asNamedGlobal, memberName } from "./resolve.js";
|
|
3
|
+
import { resolveTargetOf } from "../target.js";
|
|
4
|
+
/** Globals that are network entry points. The target comes from the first call argument. */
|
|
5
|
+
const NETWORK_GLOBALS = new Map([
|
|
6
|
+
["fetch", "network.fetch"],
|
|
7
|
+
["XMLHttpRequest", "network.xhr"],
|
|
8
|
+
["WebSocket", "network.websocket"],
|
|
9
|
+
["EventSource", "network.eventsource"],
|
|
10
|
+
]);
|
|
11
|
+
const NETWORK_NAMES = new Set(NETWORK_GLOBALS.keys());
|
|
12
|
+
/**
|
|
13
|
+
* Ways code reaches another host: fetch, XMLHttpRequest, WebSocket,
|
|
14
|
+
* EventSource, navigator.sendBeacon, and dynamic import() of an absolute
|
|
15
|
+
* URL or an expression whose destination cannot be fixed. import() of a
|
|
16
|
+
* relative path (code splitting) or a bare specifier ("lodash", "node:fs")
|
|
17
|
+
* resolves through the bundler or import map, not the network, and is not
|
|
18
|
+
* reported.
|
|
19
|
+
*/
|
|
20
|
+
export const network = ({ node, ancestors, binding }) => {
|
|
21
|
+
if (binding)
|
|
22
|
+
return null;
|
|
23
|
+
const n = node;
|
|
24
|
+
const parent = ancestors[0];
|
|
25
|
+
const firstArg = () => resolveTargetOf(callArgs(node, parent, true)?.[0]);
|
|
26
|
+
if (n.type === "ImportExpression") {
|
|
27
|
+
const target = resolveTargetOf(n["source"], "specifier");
|
|
28
|
+
if (target === "same-origin" || target === "bare")
|
|
29
|
+
return null;
|
|
30
|
+
return plain("network.import", node, target);
|
|
31
|
+
}
|
|
32
|
+
const g = asGlobalIn(n, NETWORK_NAMES);
|
|
33
|
+
if (g)
|
|
34
|
+
return match(NETWORK_GLOBALS.get(g.name), g.r, node, firstArg());
|
|
35
|
+
if (n.type === "MemberExpression" && memberName(n) === "sendBeacon") {
|
|
36
|
+
const r = asNamedGlobal(n["object"], "navigator");
|
|
37
|
+
return r ? match("network.beacon", r, node, firstArg()) : null;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/extract/recognizers/network.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAmB,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,4FAA4F;AAC5F,MAAM,eAAe,GAAgC,IAAI,GAAG,CAAC;IAC3D,CAAC,OAAO,EAAE,eAAe,CAAC;IAC1B,CAAC,gBAAgB,EAAE,aAAa,CAAC;IACjC,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAClC,CAAC,aAAa,EAAE,qBAAqB,CAAC;CACvC,CAAC,CAAC;AACH,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC;AAE3E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAe,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE;IAClE,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,CAAC,GAAG,IAAe,CAAC;IAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAwB,CAAC;IACnD,MAAM,QAAQ,GAAG,GAAkB,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzF,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAY,EAAE,WAAW,CAAC,CAAC;QACpE,IAAI,MAAM,KAAK,aAAa,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAC/D,OAAO,KAAK,CAAC,gBAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IACvC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzE,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC;QACpE,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAY,EAAE,WAAW,CAAC,CAAC;QAC7D,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for recognizing references to well-known browser globals.
|
|
3
|
+
* These only decide what a node looks like; whether the identifier is
|
|
4
|
+
* shadowed by a local is decided later from the scope annotations
|
|
5
|
+
* (see annotations.ts), which is why every result carries `via`.
|
|
6
|
+
*/
|
|
7
|
+
import type { AnyNode } from "../ast.js";
|
|
8
|
+
import type { Resolved } from "./types.js";
|
|
9
|
+
/** True for an Identifier node, optionally with the given name. */
|
|
10
|
+
export declare function isIdentifier(n: unknown, name?: string): n is AnyNode & {
|
|
11
|
+
name: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The static property name of a member expression, or null if it is dynamic.
|
|
15
|
+
* A computed name is resolved from a string literal, an expression-free
|
|
16
|
+
* template, a concatenation of literals, or an identifier the scope
|
|
17
|
+
* analysis folded from `const k = "..."`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function memberName(n: AnyNode): string | null;
|
|
20
|
+
/** True when a computed member name came from anything other than a plain string literal. */
|
|
21
|
+
export declare function isFoldedMember(n: AnyNode): boolean;
|
|
22
|
+
/** If `raw` denotes the global object (`window`, `globalThis`, `self`), how it resolves; else null. */
|
|
23
|
+
export declare function asGlobalObject(raw: AnyNode): Resolved | null;
|
|
24
|
+
/**
|
|
25
|
+
* If `raw` denotes the named global (`document`, `navigator`, `history`...),
|
|
26
|
+
* bare or as `window.<name>`, how it resolves; else null.
|
|
27
|
+
*/
|
|
28
|
+
export declare function asNamedGlobal(raw: AnyNode, name: string): Resolved | null;
|
|
29
|
+
/**
|
|
30
|
+
* If `n` is one of `names`, bare (`fetch`) or through the global object
|
|
31
|
+
* (`window.fetch`, `globalThis["fetch"]`), return which and how it resolves.
|
|
32
|
+
*/
|
|
33
|
+
export declare function asGlobalIn(n: AnyNode, names: ReadonlySet<string>): {
|
|
34
|
+
name: string;
|
|
35
|
+
r: Resolved;
|
|
36
|
+
} | null;
|
|
37
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/extract/recognizers/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS3C,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAGvF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAMpD;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAIlD;AAED,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAM5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAOzE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAOvG"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { leadingLiteral } from "../target.js";
|
|
2
|
+
import { unwrap } from "../typescript.js";
|
|
3
|
+
const GLOBAL_OBJECTS = new Set(["window", "globalThis", "self"]);
|
|
4
|
+
/** `self` is routinely a local alias for `this` in older code, so it is only probable. */
|
|
5
|
+
function globalConfidence(name) {
|
|
6
|
+
return name === "self" ? "probable" : "certain";
|
|
7
|
+
}
|
|
8
|
+
/** True for an Identifier node, optionally with the given name. */
|
|
9
|
+
export function isIdentifier(n, name) {
|
|
10
|
+
if (!n || n.type !== "Identifier")
|
|
11
|
+
return false;
|
|
12
|
+
return name === undefined || n["name"] === name;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The static property name of a member expression, or null if it is dynamic.
|
|
16
|
+
* A computed name is resolved from a string literal, an expression-free
|
|
17
|
+
* template, a concatenation of literals, or an identifier the scope
|
|
18
|
+
* analysis folded from `const k = "..."`.
|
|
19
|
+
*/
|
|
20
|
+
export function memberName(n) {
|
|
21
|
+
if (n.type !== "MemberExpression")
|
|
22
|
+
return null;
|
|
23
|
+
const prop = n["property"];
|
|
24
|
+
if (n["computed"] !== true)
|
|
25
|
+
return isIdentifier(prop) ? prop.name : null;
|
|
26
|
+
const lit = leadingLiteral(prop);
|
|
27
|
+
return lit !== null && lit.complete ? lit.text : null;
|
|
28
|
+
}
|
|
29
|
+
/** True when a computed member name came from anything other than a plain string literal. */
|
|
30
|
+
export function isFoldedMember(n) {
|
|
31
|
+
const m = (n.type === "AssignmentExpression" ? n["left"] : n);
|
|
32
|
+
if (m.type !== "MemberExpression" || m["computed"] !== true)
|
|
33
|
+
return false;
|
|
34
|
+
return m["property"].type !== "Literal";
|
|
35
|
+
}
|
|
36
|
+
/** If `raw` denotes the global object (`window`, `globalThis`, `self`), how it resolves; else null. */
|
|
37
|
+
export function asGlobalObject(raw) {
|
|
38
|
+
const n = unwrap(raw);
|
|
39
|
+
if (isIdentifier(n) && GLOBAL_OBJECTS.has(n.name)) {
|
|
40
|
+
return { confidence: globalConfidence(n.name), via: n };
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* If `raw` denotes the named global (`document`, `navigator`, `history`...),
|
|
46
|
+
* bare or as `window.<name>`, how it resolves; else null.
|
|
47
|
+
*/
|
|
48
|
+
export function asNamedGlobal(raw, name) {
|
|
49
|
+
const n = unwrap(raw);
|
|
50
|
+
if (isIdentifier(n, name))
|
|
51
|
+
return { confidence: "certain", via: n };
|
|
52
|
+
if (n.type === "MemberExpression" && memberName(n) === name) {
|
|
53
|
+
return asGlobalObject(n["object"]);
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* If `n` is one of `names`, bare (`fetch`) or through the global object
|
|
59
|
+
* (`window.fetch`, `globalThis["fetch"]`), return which and how it resolves.
|
|
60
|
+
*/
|
|
61
|
+
export function asGlobalIn(n, names) {
|
|
62
|
+
if (isIdentifier(n))
|
|
63
|
+
return names.has(n.name) ? { name: n.name, r: { confidence: "certain", via: n } } : null;
|
|
64
|
+
if (n.type !== "MemberExpression")
|
|
65
|
+
return null;
|
|
66
|
+
const prop = memberName(n);
|
|
67
|
+
if (prop === null || !names.has(prop))
|
|
68
|
+
return null;
|
|
69
|
+
const r = asGlobalObject(n["object"]);
|
|
70
|
+
return r ? { name: prop, r } : null;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/extract/recognizers/resolve.ts"],"names":[],"mappings":"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"}
|