[PR #3036] [CLOSED] fix(javascript): keep keyed-store reads out of endpoints #5572

Closed
opened 2026-10-31 01:07:41 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3036
Author: @alfredo1491
Created: 10/13/2026
Status: ❌ Closed

Base: main ← Head: fix/javascript-keyed-store-endpoints


📝 Commits (2)

  • 927f6fa fix(javascript): keep VS Code extension state reads out of endpoints
  • c579f5c fix(javascript): treat undici headersList as a keyed collection

📊 Changes

3 files changed (+100 additions, -9 deletions)

View changed files

📝 src/domain/javascript/javascriptSemanticAnalysis.ts (+41 -4)
📝 src/domain/javascript/javascriptStaticAnalysisHelpers.ts (+12 -5)
📝 src/domain/webBundleAnalyzer.test.ts (+47 -0)

📄 Description

Problem

Follow-up to #2402. Static endpoint extraction still reports reads of two key/value stores as network endpoints, because their .get(key) / .delete(key) calls look like HTTP client calls:

  • undici headersList: bundled undici (the implementation behind Node's fetch) reads and removes headers through request.headersList.get("location") and headersList.delete("authorization"). headers and searchParams are already treated as keyed collections, but headersList was not.
  • VS Code extension state (Memento): context.globalState.get("lastVersion") and workspaceState.get("closedRepositories", []) report every literal state key as an endpoint.

Across the 38 bundled dist/*.js files of the extensions shipped with VS Code, only 14 of 309 reported network endpoints are URL- or path-shaped.

Change

  • isKeyedCollectionReceiver also accepts the headersList member, with the same rule as headers/searchParams: spelling alone never drops URL- or path-shaped literals.
  • classifyParsedJavaScriptOpenReceivers records an extension-state fact for .get on a globalState/workspaceState member. VS Code passes the ExtensionContext to activate, so the member has no import origin of its own; the fact therefore also requires a binding in the same module whose origin is vscode (namespace/default import or require), reusing the origins the configuration receiver check from #2402 relies on. Without that proof, the endpoint is kept.
  • endpointArgument skips non-URL literals for the new fact, in both application and web bundle analysis.

Two commits, one per store, so either can be reviewed or dropped independently.

Measurements

analyzeJavaScriptStaticSource over the 38 bundled extension dist/*.js files of VS Code (resources/app/extensions/*/dist), measured against main @ 0e6eca408 before rebasing:

main this PR
network endpoints 309 284
copilot 194 171
git 8 7
microsoft-authentication 3 2

Most of the gain is undici (headersList). Memento contributes little here because most extensions read state through constant keys, which were never endpoints; only 11 literal-key Memento reads exist in these bundles.

Receiver classification time is unchanged: 3 runs on copilot's 19.7 MB extension.js measured 27.8/31.1/30.7 s after vs 27.4/29.5/30.8 s before. The module-level vscode proof runs only when a candidate globalState/workspaceState read exists.

Verification

  • src/domain/webBundleAnalyzer.test.ts: new two-analyzer case for extension state (namespace import, require, and a non-vscode require that keeps every key), and the keyed-collection case extended with headersList reads plus URL/path literals that stay endpoints.
  • vitest run src/domain/webBundleAnalyzer.test.ts src/domain/javascript/ src/application/javascript/ (rebased on main @ 80592b82a): 1595 passed.
  • npm run check:fast (typecheck + lint, via the Husky pre-push hook): passed.

Unavailable coverage: boundary/acceptance projects and the source CLI were not run on this Windows host (the native addon cannot be built outside the Linux/MinGW lane); measurements come from the domain analyzer directly. No real-provider lanes apply.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3036 **Author:** [@alfredo1491](https://github.com/alfredo1491) **Created:** 10/13/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/javascript-keyed-store-endpoints` --- ### 📝 Commits (2) - [`927f6fa`](https://github.com/morluto/rea/commit/927f6fa419cf9193164fafc0a4491134dbca29dd) fix(javascript): keep VS Code extension state reads out of endpoints - [`c579f5c`](https://github.com/morluto/rea/commit/c579f5c56651fda290dbfd03993de575e9dee066) fix(javascript): treat undici headersList as a keyed collection ### 📊 Changes **3 files changed** (+100 additions, -9 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/javascript/javascriptSemanticAnalysis.ts` (+41 -4) 📝 `src/domain/javascript/javascriptStaticAnalysisHelpers.ts` (+12 -5) 📝 `src/domain/webBundleAnalyzer.test.ts` (+47 -0) </details> ### 📄 Description ## Problem Follow-up to #2402. Static endpoint extraction still reports reads of two key/value stores as `network` endpoints, because their `.get(key)` / `.delete(key)` calls look like HTTP client calls: - **undici `headersList`**: bundled undici (the implementation behind Node's `fetch`) reads and removes headers through `request.headersList.get("location")` and `headersList.delete("authorization")`. `headers` and `searchParams` are already treated as keyed collections, but `headersList` was not. - **VS Code extension state (Memento)**: `context.globalState.get("lastVersion")` and `workspaceState.get("closedRepositories", [])` report every literal state key as an endpoint. Across the 38 bundled `dist/*.js` files of the extensions shipped with VS Code, only 14 of 309 reported network endpoints are URL- or path-shaped. ## Change - `isKeyedCollectionReceiver` also accepts the `headersList` member, with the same rule as `headers`/`searchParams`: spelling alone never drops URL- or path-shaped literals. - `classifyParsedJavaScriptOpenReceivers` records an `extension-state` fact for `.get` on a `globalState`/`workspaceState` member. VS Code passes the `ExtensionContext` to `activate`, so the member has no import origin of its own; the fact therefore also requires a binding in the same module whose origin is `vscode` (namespace/default import or `require`), reusing the origins the configuration receiver check from #2402 relies on. Without that proof, the endpoint is kept. - `endpointArgument` skips non-URL literals for the new fact, in both application and web bundle analysis. Two commits, one per store, so either can be reviewed or dropped independently. ## Measurements `analyzeJavaScriptStaticSource` over the 38 bundled extension `dist/*.js` files of VS Code (`resources/app/extensions/*/dist`), measured against `main` @ 0e6eca408 before rebasing: | | `main` | this PR | |---|---|---| | network endpoints | 309 | 284 | | copilot | 194 | 171 | | git | 8 | 7 | | microsoft-authentication | 3 | 2 | Most of the gain is undici (`headersList`). Memento contributes little here because most extensions read state through constant keys, which were never endpoints; only 11 literal-key Memento reads exist in these bundles. Receiver classification time is unchanged: 3 runs on copilot's 19.7 MB `extension.js` measured 27.8/31.1/30.7 s after vs 27.4/29.5/30.8 s before. The module-level `vscode` proof runs only when a candidate `globalState`/`workspaceState` read exists. ## Verification - `src/domain/webBundleAnalyzer.test.ts`: new two-analyzer case for extension state (namespace import, require, and a non-`vscode` require that keeps every key), and the keyed-collection case extended with `headersList` reads plus URL/path literals that stay endpoints. - `vitest run src/domain/webBundleAnalyzer.test.ts src/domain/javascript/ src/application/javascript/` (rebased on main @ 80592b82a): 1595 passed. - `npm run check:fast` (typecheck + lint, via the Husky pre-push hook): passed. Unavailable coverage: boundary/acceptance projects and the source CLI were not run on this Windows host (the native addon cannot be built outside the Linux/MinGW lane); measurements come from the domain analyzer directly. No real-provider lanes apply. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:07:41 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5572
No description provided.