fix(google): bound JSON response reads to prevent OOM#96324
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 25, 2026, 5:03 AM ET / 09:03 UTC. Summary PR surface: Source +72. Total +72 across 6 files. Reproducibility: yes. source inspection is enough to reproduce the review-relevant behavior: current main has the unbounded Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Keep the Google bounded-read hardening, but route provider success JSON through the shared helper with explicit per-surface caps, remove the OAuth compile errors, size media caps to valid base64 payloads, and require redacted real behavior proof before merge. Do we have a high-confidence way to reproduce the issue? Yes, source inspection is enough to reproduce the review-relevant behavior: current main has the unbounded Is this the best way to solve the issue? No. Bounded reads are the right direction, but this PR is not the best mergeable fix until it uses the shared helper, repairs the OAuth token compile error, sizes media caps correctly, and adds real behavior proof. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 2b8c089b7699. Label changesLabel justifications:
Evidence reviewedPR surface: Source +72. Total +72 across 6 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
01e7df5 to
507f5ab
Compare
Replace unbounded await response.json() with readResponseWithLimit (1 MiB cap) across embedding-batch, image-generation, media-understanding, oauth.token, oauth.project, and speech providers. A malicious or faulty Google API endpoint returning an oversized JSON response body would previously buffer the entire body in memory before parsing. readResponseWithLimit cancels the stream once the cap is reached, preventing unbounded buffering. - embedding-batch: bound file upload, batch status, and result reads (3 call sites, plus error-path text() via existing pattern) - image-generation-provider: bound image generation response read - media-understanding-provider: bound media description response read - oauth.token: bound token exchange JSON response read - oauth.project: bound 5 JSON response reads (userinfo, project list, error payload, token refresh, onboarding LRO) - speech-provider: bound speech synthesis response read Co-Authored-By: Claude <[email protected]>
speech-provider, media-understanding-provider, and oauth.project were missing their JSON_RESPONSE_MAX_BYTES constant declarations after the batch script added readResponseWithLimit usage but skipped the constant. Co-Authored-By: Claude <[email protected]>
507f5ab to
fbe8946
Compare
The batch script replaced await response.json() but dropped the const declarations, causing 'data' and 'errorPayload' to be undefined at runtime. Also removed the duplicate readResponseWithLimit import. Co-Authored-By: Claude <[email protected]>
|
Closing: source branch has been deleted, CI can no longer recover. |
What Problem This Solves
Replace unbounded
await response.json()withreadResponseWithLimit(1 MiB cap)across Google embedding-batch, image-generation, media-understanding, oauth.token,
oauth.project, and speech providers (11 call sites in 6 files) — the symmetric
Google-endpoint counterpart to bound-stream work already merged for Google prompt
cache (#95417) and other providers (#95420, #95218).
A malicious or faulty Google API endpoint returning an oversized JSON response body
would previously buffer the entire body in memory before parsing. The Google
video-generation module already uses
readResponseWithLimitfor downloads (#95417handles the prompt-cache path), but these 6 modules were still unbounded.
Evidence
npx oxlintexits 0 on changed files;git diff --checkcleanprompt cache), fix(agents): bound OpenRouter model catalog response reads #95420, fix(agents): bound OpenRouter model-scan catalog success body #95418, fix(agents): bound provider JSON response reads #95218 — 1 MiB cap is safe for batch status,
OAuth tokens, speech metadata, and image generation responses
await response.json()wouldallow an oversized streamed body to buffer without bound
Summary
Bound 11 unbounded JSON response reads in Google providers with 1 MiB cap.
Changes
extensions/google/embedding-batch.ts— bound file upload, batch status, andresult reads (3 call sites)
extensions/google/image-generation-provider.ts— bound image generationresponse read
extensions/google/media-understanding-provider.ts— bound media descriptionresponse read
extensions/google/oauth.token.ts— bound token exchange JSON response readextensions/google/oauth.project.ts— bound 5 JSON response reads (userinfo,project list, error payload, token refresh, onboarding LRO)
extensions/google/speech-provider.ts— bound speech synthesis response read