fix(fal): bound video generation JSON response reads#96977
fix(fal): bound video generation JSON response reads#96977Monkey-wusky wants to merge 2 commits into
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. This PR is superseded by a broader open fal hardening PR that covers the same video JSON path plus fal image/music, is cleanly mergeable, and has stronger proof. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Close this PR and keep the remaining review/landing decision on #96886. So I’m closing this here and keeping the remaining discussion on #96886. Review detailsBest possible solution: Close this PR and keep the remaining review/landing decision on #96886. Do we have a high-confidence way to reproduce the issue? Yes. Current main calls Is this the best way to solve the issue? No. Reusing Security review: Security review cleared: The diff attempts to reduce untrusted provider response-body memory exposure and does not add dependencies, workflow permissions, secret handling, or downloaded-code execution. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 9a735bea03f6. |
|
Closing as superseded by the broader fal hardening PR #96886 which covers video + image + music with stronger proof. |
What Problem This Solves
fetchFalJsoninextensions/fal/video-generation-provider.tsreads the video generation submit, poll, and completion responses with an unboundedawait response.json(). The shared fetch layer enforces an abort timeout but does not bound body size, so a misbehaving or compromised fal endpoint can stream an arbitrarily large (orContent-Length-less, never-ending) JSON body thatres.json()buffers whole into memory — an OOM vector on the video generation queue path.Changes
fetchFalJsonthrough the shared bounded readerreadProviderJsonResponse(16 MiB cap =PROVIDER_JSON_RESPONSE_MAX_BYTES, re-exported viaopenclaw/plugin-sdk/provider-http): it reads under the shared 16 MiB cap, cancels the underlying stream on overflow, and throwsfal video generation failed: JSON response exceeds <N> bytes.try { return await response.json() } catchin favour ofreadProviderJsonResponsewhich already provides label-scoped error messages.Real behavior proof
Content-Lengthand an oversized / never-ending body must not be buffered whole; the read must stop at the cap, cancel the stream, and throw a bounded error — while valid small responses still parse unchanged.ReadableStreamResponse delivering 32 MiB in 1 MiB chunks (double the 16 MiB cap) drives the realprovider.generateVideo. The test asserts the bounded reader cancels the stream mid-flight and never pulls the full advertised payload.bytesPulled < 32 MiBconfirms no full buffering.