[PR #874] [MERGED] fix(javascript): keep keyed-collection reads out of endpoints #2311

Closed
opened 2026-10-16 21:17:07 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/874
Author: @kaoru0822-kitauji
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/7/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/javascript-http-method-endpoints


📝 Commits (2)

  • eb68761 fix(javascript): keep keyed-collection reads out of endpoints
  • 00f707b fix(javascript): filter keyed-collection receivers only for get/delete

📊 Changes

4 files changed (+77 additions, -8 deletions)

View changed files

📝 src/domain/javascriptStaticAnalysisCalls.ts (+1 -1)
📝 src/domain/javascriptStaticAnalysisHelpers.ts (+47 -6)
📝 src/domain/webBundleAnalyzer.test.ts (+28 -0)
📝 src/domain/webBundleAnalyzerInspection.ts (+1 -1)

📄 Description

Summary

endpointArgument is shared by analyze_javascript_application static analysis and analyze_web_bundle. It read the first literal argument of any call named get, post, put, patch, delete, or request as an HTTP request URL. Reads of built-in keyed collections therefore became network endpoints that were reported as observed, with exact confidence:

new URLSearchParams(location.search).get("q");   // endpoint "q"
response.headers.get("content-type");            // endpoint "content-type"
new Map().get("map-key");                        // endpoint "map-key"
new URL(location.href).searchParams.get("page"); // endpoint "page"

Now a get or delete call, the two methods these collections share with HTTP clients, is skipped only when the receiver is provably a keyed collection:

  • a constructed Map, WeakMap, Set, WeakSet, Headers, FormData, or URLSearchParams (new X(...).get(...));
  • the platform headers / searchParams property (response.headers, request?.headers, url.searchParams).

post, put, patch, and request are never filtered, so api.headers.post("/v1/headers") keeps its endpoint (Codex review). Any other receiver may be an HTTP client with a configured base URL, so it keeps its endpoint as before. That includes api.get("users"), client.delete("x"), and minified e.get("x"). This follows Codex's first suggestion: disambiguate known non-network receivers instead of dropping ambiguous calls.

An earlier revision of this PR required URL-like literals. As Codex pointed out, that silently dropped base-URL requests such as api.get("users"). Marking those calls unknown instead would make nearly every application graph partial, because any partial file marks the whole graph partial. This revision only removes provable false positives.

No schema or catalog change.

Verification

  • src/domain/webBundleAnalyzer.test.ts: a new parity case keeps axios.get(url), api.get("users"), and client.delete("cache-key"), and excludes the seven provable collection reads. It fails on main.
  • Rebuilt CLI sample: endpoints https://api.example.com/users, http://legacy.example.com/, /api/login, file, cache-key. q and content-type are gone. formData.get and a Map held in a variable remain, because their receivers are not provable without binding resolution.
  • npm run check:changed (37 files, 749 tests) passes. npm run test:focused on the JavaScript/Electron/web-bundle boundary and acceptance tests (63 files) also passes. It excludes the two V8 Inspector runtime files, which fail identically on unmodified main on this host.

No Hopper/Ghidra/IDA verification is needed.

🤖 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/874 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/7/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/javascript-http-method-endpoints` --- ### 📝 Commits (2) - [`eb68761`](https://github.com/morluto/rea/commit/eb68761eb0a35b876e33dd6115d0d07f97e99dd5) fix(javascript): keep keyed-collection reads out of endpoints - [`00f707b`](https://github.com/morluto/rea/commit/00f707b250451246d69a1205c39c6843fab6bb5b) fix(javascript): filter keyed-collection receivers only for get/delete ### 📊 Changes **4 files changed** (+77 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/javascriptStaticAnalysisCalls.ts` (+1 -1) 📝 `src/domain/javascriptStaticAnalysisHelpers.ts` (+47 -6) 📝 `src/domain/webBundleAnalyzer.test.ts` (+28 -0) 📝 `src/domain/webBundleAnalyzerInspection.ts` (+1 -1) </details> ### 📄 Description ## Summary `endpointArgument` is shared by `analyze_javascript_application` static analysis and `analyze_web_bundle`. It read the first literal argument of **any** call named `get`, `post`, `put`, `patch`, `delete`, or `request` as an HTTP request URL. Reads of built-in keyed collections therefore became network endpoints that were reported as observed, with exact confidence: ```js new URLSearchParams(location.search).get("q"); // endpoint "q" response.headers.get("content-type"); // endpoint "content-type" new Map().get("map-key"); // endpoint "map-key" new URL(location.href).searchParams.get("page"); // endpoint "page" ``` Now a `get` or `delete` call, the two methods these collections share with HTTP clients, is skipped only when the receiver is **provably** a keyed collection: - a constructed `Map`, `WeakMap`, `Set`, `WeakSet`, `Headers`, `FormData`, or `URLSearchParams` (`new X(...).get(...)`); - the platform `headers` / `searchParams` property (`response.headers`, `request?.headers`, `url.searchParams`). `post`, `put`, `patch`, and `request` are never filtered, so `api.headers.post("/v1/headers")` keeps its endpoint (Codex review). Any other receiver may be an HTTP client with a configured base URL, so it keeps its endpoint as before. That includes `api.get("users")`, `client.delete("x")`, and minified `e.get("x")`. This follows Codex's first suggestion: disambiguate known non-network receivers instead of dropping ambiguous calls. > An earlier revision of this PR required URL-like literals. As Codex pointed out, that silently dropped base-URL requests such as `api.get("users")`. Marking those calls unknown instead would make nearly every application graph `partial`, because any partial file marks the whole graph partial. This revision only removes provable false positives. No schema or catalog change. ## Verification - `src/domain/webBundleAnalyzer.test.ts`: a new parity case keeps `axios.get(url)`, `api.get("users")`, and `client.delete("cache-key")`, and excludes the seven provable collection reads. It fails on `main`. - Rebuilt CLI sample: endpoints `https://api.example.com/users`, `http://legacy.example.com/`, `/api/login`, `file`, `cache-key`. `q` and `content-type` are gone. `formData.get` and a Map held in a variable remain, because their receivers are not provable without binding resolution. - `npm run check:changed` (37 files, 749 tests) passes. `npm run test:focused` on the JavaScript/Electron/web-bundle boundary and acceptance tests (63 files) also passes. It excludes the two V8 Inspector runtime files, which fail identically on unmodified `main` on this host. No Hopper/Ghidra/IDA verification is needed. 🤖 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-16 21:17:07 +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#2311
No description provided.