Commit Graph

62479 Commits

Author SHA1 Message Date
Yuval Dinodia 028fc97809 fix(memory-core): write MEMORY.md atomically during short-term promotion (#108397)
* fix(memory-core): write MEMORY.md atomically during short-term promotion

applyShortTermPromotions rewrote MEMORY.md with a single non-atomic
fs.writeFile, which truncates the file before streaming the new content.
An OS write failure part way through (for example EFBIG on a size-limited
or full volume) left MEMORY.md truncated to the bytes written before the
failure, permanently dropping user long-term memory. The dreaming cron
path invokes this writer automatically, and the recall store is only
updated after the write, so the promotion stays eligible and the next
run reads the already-truncated file.

Route the write through replaceFileAtomic (temp file, fsync, atomic
rename), the same durable-write helper the sibling DREAMS.md writer in
this extension already uses. On failure the temp file is discarded and
the existing MEMORY.md is left untouched; on success the content and the
existing file mode are preserved.

* fix(memory-core): harden atomic promotion durability

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 0317d7e628)
2026-08-06 18:54:35 +08:00
NIO e5db650a48 fix(clickclack): bound websocket handshake waits at 30s (#106485)
* fix(clickclack): bound websocket handshake waits at 30s

* test(clickclack): prove WebSocket handshake deadline

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 3eec404aab)
2026-08-06 18:53:41 +08:00
krissding cc0e215fa4 fix(sessions): stop leaking file path as prompt content on read failure (#108546)
* fix(sessions): stop leaking file path as prompt content on read failure

When readFileSync fails for a valid file path, resolvePromptInput returns
the raw path string as prompt content instead of undefined. This injects
filesystem paths into the LLM context. The existing console.error warning
still fires; the caller already handles undefined returns correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: cover unreadable prompt paths

* test: use tracked resource loader temp dirs

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit c924819292)
2026-08-06 18:53:30 +08:00
xingzhou f8f1e8bb0f fix(extensions): prevent corrupted UTF-8 in api.exec output (#108365)
* fix(extensions): preserve split UTF-8 in api.exec

* test(agents): cover incomplete exec UTF-8 at EOF

Co-authored-by: zhang-guiping <zhang.guiping@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 3b51889c3b)
2026-08-06 18:53:29 +08:00
zw-xysk ea438f5073 fix(synology-chat): bound outbound NAS response bodies to prevent Gateway OOM (#105089)
* fix(synology-chat): settle user_list overflow without hanging

Cap reads at 1 MiB with Buffer concat. On overflow, finish the promise
before destroy() — bare destroy often skips end/error and hung the test.

* fix(synology-chat): share bounded user-list reader

Co-authored-by: zw-xysk <zhao.wang1@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 30c257f6b4)
2026-08-06 18:52:59 +08:00
wahaha1223 6ef58ba3f2 fix(memory): preserve UTF-8 when qmd output splits across pipe chunks (#107263)
* fix(memory): preserve UTF-8 across fragmented qmd output chunks

* fix(memory): decode qmd streams at UTF-8 boundary

Co-authored-by: wahaha1223 <0668001153@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 7f36f49052)
2026-08-06 18:52:52 +08:00
sunlit-deng 3c147ad8ce fix(openai): bound embedding batch file downloads (#98554)
* fix(openai): bound embedding batch file downloads

* fix(openai): bound batch output records

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit ce4a259485)
2026-08-06 18:52:46 +08:00
lsr911 6a7362ce4c fix(minimax): bound OAuth JSON response via shared provider reader (#96322)
Use readProviderJsonResponse (shared 16 MiB default cap) instead of
unbounded response.json() for MiniMax OAuth authorization code endpoint.

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
(cherry picked from commit 4a96c06615)
2026-08-06 18:52:46 +08:00
NIO dca51df186 fix(moonshot): bound video description JSON response reads (#96502)
* fix(moonshot): bound video description JSON response reads

The Moonshot video description endpoint used an unbounded await res.json()
to parse the media understanding response. Route through
readProviderJsonResponse (16 MiB cap) to match the bound already in
place for other media understanding providers (xai, openrouter).

AI-assisted.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(moonshot): add bounds and malformed-JSON coverage for video description

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 765d05c2e4)
2026-08-06 18:52:46 +08:00
cxbAsDev b8791fe9e8 fix(cli): bound docs search API response reads with committed test (#98188)
(cherry picked from commit f284ce3b4d)
2026-08-06 18:52:46 +08:00
Agustin Rivera 3993735075 fix(pdf): guard native provider requests (#97872)
* fix(pdf): guard native provider requests

* fix(pdf): preserve configured origin trust

* fix(pdf): preserve resolver compatibility

(cherry picked from commit b7b2e1f77e)
2026-08-06 18:52:46 +08:00
pick-cat 8c4f9a87a8 fix(nextcloud-talk): bound bot preflight error reads (#97811)
Co-authored-by: Pick-cat <266665499+Pick-cat@users.noreply.github.com>
(cherry picked from commit 09167523bf)
2026-08-06 18:52:45 +08:00
cxbAsDev d08f93efdf fix(discord): bound PluralKit and voice-message JSON reads
(cherry picked from commit 597a0ba43c)
2026-08-06 18:52:42 +08:00
cxbAsDev 9b4549738d fix(agents): bound WHAM usage probe JSON response reads
(cherry picked from commit 0ce10d7793)
2026-08-06 18:52:31 +08:00
Vincent Koc 6a8849886e fix(provider-usage): bound usage response body reads
(cherry picked from commit db2786bde1)
2026-08-06 18:52:31 +08:00
Alix-007 0eeedcb41d fix(xai): bound video response body reads
(cherry picked from commit 46e119074e)
2026-08-06 18:52:31 +08:00
NIO a4eb031ccd fix(github-copilot): bound login JSON response reads
(cherry picked from commit 748bea3434)
2026-08-06 18:52:31 +08:00
wangmiao0668000666 d9794886e4 fix(comfy): bound JSON response reads via readProviderJsonResponse
(cherry picked from commit bf66b4e1ea)
2026-08-06 18:52:31 +08:00
wangmiao0668000666 1747306515 fix(video-generation): bound DashScope JSON response reads
(cherry picked from commit 238398e331)
2026-08-06 18:52:31 +08:00
Alix-007 e40f3ee89a fix(vydra): bound control response reads
Reviewed and accepted after live preflight: mergeable clean, checks passing, no unresolved review threads.

(cherry picked from commit 74a9beb83f)
2026-08-06 18:52:30 +08:00
Alix-007 526e0a204e fix(fal): bound music/video generation response reads
Reviewed and accepted after live preflight: mergeable clean, checks passing, no unresolved review threads.

(cherry picked from commit ce1217a49c)
2026-08-06 18:52:30 +08:00
Alix-007 5e38550f71 fix(together, pixverse): bound video response reads
Reviewed and accepted after live preflight: mergeable clean, checks passing, no unresolved review threads.

(cherry picked from commit ca1bc58759)
2026-08-06 18:52:30 +08:00
Alix-007 66135d601d fix(openai): bound video create-submit response reads
Reviewed and accepted after live preflight: mergeable clean, checks passing, no unresolved review threads.

(cherry picked from commit f0e2f7b4f5)
2026-08-06 18:52:24 +08:00
Alix-007 cef4aa6f13 fix(runway): bound video create/poll response reads
Reviewed and accepted after live preflight: mergeable clean, checks passing, no unresolved review threads.

(cherry picked from commit 63b089383a)
2026-08-06 18:52:24 +08:00
Alix-007 35b54ef40b fix: bound APNs relay response body so an oversized relay reply can't exhaust gateway memory
Reviewed and accepted after live preflight: mergeable clean, checks passing, no unresolved review threads.

(cherry picked from commit 89b5a87909)
2026-08-06 18:52:24 +08:00
cxbAsDev 8ab9d1010a fix(xai): bound OAuth response reads to prevent OOM (#97615)
Replace unbounded response.text() in readResponseBody and
response.json() in the device-code polling loop with
readResponseWithLimit (16 MiB cap).

(cherry picked from commit d5aca1d6d2)
2026-08-06 18:52:08 +08:00
NIO 804873dbc4 fix(ollama): bound cloud-auth 401 JSON response reads
(cherry picked from commit a82cff8892)
2026-08-06 18:51:45 +08:00
NIO be5e8ce978 fix(google): bound embedding-batch JSON response reads (#97535)
* fix(google): bound embedding-batch JSON response reads

* fix(google): repair embedding-batch test types and lint

---------

Co-authored-by: NIO <nocodet@mail.com>
(cherry picked from commit 91297bf420)
2026-08-06 18:51:45 +08:00
NIO 027f2d853a fix(telegram): bound getChat Bot API response reads (#97274)
* fix(telegram): bound getChat Bot API response reads

* fix(telegram): repair getChat bound-read type and proof script lint

---------

Co-authored-by: NIO <nocodet@mail.com>
(cherry picked from commit b948c86b2a)
2026-08-06 18:51:45 +08:00
NIO 22565f7a1d fix(openai): bound embedding-batch and realtime session JSON response reads (#97533)
(cherry picked from commit 4c477ee632)
2026-08-06 18:51:45 +08:00
NIO 9cba1e77cb fix(signal): bound GitHub release info JSON response with readProviderJsonResponse (#97536)
Replace bare `await response.json()` in `installSignalCliFromRelease` with
`readProviderJsonResponse` (16 MiB cap, stream cancel on overflow). The
external GitHub Releases endpoint can include a large `body` changelog field;
the error path was already guarded but the success path was unbounded.
The existing inner catch continues to convert overflow errors into the
graceful `{ ok: false, error: "Failed to parse signal-cli release info." }` path.

Adds a regression test verifying the stream is cancelled before all chunks are
read on an oversized 20 MiB streaming response.

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 51064bda4d)
2026-08-06 18:51:44 +08:00
Alix-007 9e337073c9 fix(openrouter): bound video response reads
Route OpenRouter video submit and poll success JSON through the shared bounded provider JSON reader, preserving malformed-response mapping and SSRF request policy coverage.

(cherry picked from commit 48f34b1d4d)
2026-08-06 18:51:44 +08:00
NIO da7a0da19a fix(openrouter): bound generation-cost JSON response reads (#97490)
(cherry picked from commit c0883a531d)
2026-08-06 18:51:44 +08:00
NIO 619d50888a fix(deepinfra): bound video generation JSON response reads (#97486)
(cherry picked from commit 0d59280131)
2026-08-06 18:51:44 +08:00
Alix-007 286ca2feb7 fix(speech): bound TTS response reads (#96874)
(cherry picked from commit 2f851ecfe9)
2026-08-06 18:51:44 +08:00
Alix-007 b1d2bff30e fix(minimax): bound video control response reads (#96889)
* fix(minimax): bound image/video success response reads

MiniMax image generation and video generation (task submit + status poll)
read their success responses through unbounded `await response.json()`, so
a misbehaving or hostile endpoint could stream an arbitrarily large body
into memory before parsing and exhaust the process. Read those success
bodies through the shared bounded reader (16 MiB cap, the same limit other
bundled providers and the sibling MiniMax web-search provider already use)
and cancel the stream on overflow. The error-body path is already bounded
via assertOkOrThrowHttpError; this closes the matching success-JSON gap.
MiniMax TTS is already bounded and is left unchanged.

AI-assisted.

* fix(minimax): bound video metadata response reads

* fix(minimax): leave image response sizing to image hardening

* fix(minimax): bound image/video success response reads

MiniMax image generation and video generation (task submit + status poll)
read their success responses through unbounded `await response.json()`, so
a misbehaving or hostile endpoint could stream an arbitrarily large body
into memory before parsing and exhaust the process. Read those success
bodies through the shared bounded reader (16 MiB cap, the same limit other
bundled providers and the sibling MiniMax web-search provider already use)
and cancel the stream on overflow. The error-body path is already bounded
via assertOkOrThrowHttpError; this closes the matching success-JSON gap.
MiniMax TTS is already bounded and is left unchanged.

AI-assisted.

* fix(minimax): bound video metadata response reads

(cherry picked from commit 25e184aeab)
2026-08-06 18:51:44 +08:00
Alix-007 2d26492fea fix(mattermost): bound successful REST JSON/text response reads (#96033)
* fix(mattermost): bound successful REST JSON/text response reads

The Mattermost REST client already bounds error bodies
(readResponseTextLimited) and streams guarded responses without buffering,
but the success path still called `await res.json()` / `await res.text()`,
reading the whole body into memory before parsing. A self-hosted or
compromised Mattermost server can return an arbitrarily large (or
never-terminating, content-length-less) JSON/text body and force the plugin
to buffer it unbounded.

Read successful JSON through the shared readProviderJsonResponse (16 MiB cap,
cancels the stream and throws a bounded error on overflow, same as the
provider HTTP path) and cap non-JSON success bodies with readResponseTextLimited.
uploadMattermostFile's file-info JSON is bounded the same way.

Symmetric follow-up to the #95103 / #95108 response-limit campaign.

AI-assisted.

* fix(mattermost): bound probe success JSON reads

* fix(mattermost): reject oversized success text bodies

(cherry picked from commit 9241b9701d)
2026-08-06 18:51:43 +08:00
Alix-007 607cf241d0 fix(embedding): bound OpenAI-compatible embedding response reads (#96868)
* fix(embedding): bound OpenAI-compatible embedding response reads

* test(embedding): avoid loop-condition lint in stream proof

(cherry picked from commit f1e4980a97)
2026-08-06 18:51:43 +08:00
NIO c7d3779f4f Fix/zalo bound api json response reads (#97277)
* fix(zalo): bound Bot API JSON response reads via readProviderJsonResponse

* test(zalo): keep API proof in focused coverage

---------

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
(cherry picked from commit 38ddcef78f)
2026-08-06 18:51:43 +08:00
NIO c43269ccf9 Fix/discord bound probe getme json reads (#97278)
* fix(discord): bound probe getMe JSON response reads

* test(discord): add oversized probe getMe JSON regression

* test(discord): add loopback proof for bounded probe getMe reads

* fix(scripts): satisfy oxlint in discord probe proof script

* test(discord): keep probe proof in focused coverage

---------

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
(cherry picked from commit 7ba9212665)
2026-08-06 18:51:43 +08:00
mushuiyu886 cfb56d5baa fix(clickclack): bound REST success JSON response reads (#96970)
* fix(clickclack): bound REST success JSON response reads

* test(clickclack): harden response cap proof

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit f4fa10c2c5)
2026-08-06 18:51:43 +08:00
mushuiyu886 ef1dc4645f fix(google): bound TTS success JSON response reads (#96984)
(cherry picked from commit 5ccfc97b31)
2026-08-06 18:51:43 +08:00
mushuiyu886 9acfa081d1 fix(google-media): bound JSON response reads (#96920)
* fix(google-media): bound JSON response reads

* test(google): relax media response cap assertion

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit a7bfc06f45)
2026-08-06 18:51:38 +08:00
NIO aece31125b fix(image-gen): bound image generation provider JSON response reads (#96495)
* fix(image-gen): bound image generation provider JSON response reads

Route success JSON reads through readProviderJsonResponse (16 MiB cap)
in openrouter, google, fal, minimax, openai, and vydra image generation
providers to prevent OOM from oversized or hostile endpoint responses.
Mirrors the response-limit campaign already applied to other provider paths.

AI-assisted.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(image-gen): size bounded JSON caps for inline image payloads

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sallyom <somalley@redhat.com>
(cherry picked from commit 527f8f0cbb)
2026-08-06 18:51:38 +08:00
NIO 3ee8181303 fix(github-copilot): bound model discovery and embeddings JSON response (#96499)
* fix(github-copilot): bound model discovery and embeddings JSON response reads

The GitHub Copilot embeddings plugin already bounds its error response
bodies via readResponseTextLimited, but the success JSON reads for both
model discovery and the embeddings call used unbounded response.json().
Route both through readProviderJsonResponse (16 MiB cap).

Update isCopilotSetupError to recognise the new error label prefix so
auto-selection still falls through on malformed discovery responses.
Update tests to use proper Response objects and the new error messages.

AI-assisted.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(github-copilot): use memory embedding response cap

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sallyom <somalley@redhat.com>
(cherry picked from commit 1aa7cafc35)
2026-08-06 18:51:34 +08:00
NIO bfc4c146ae fix(speech): bound TTS/STT voice-list and transcription JSON response reads (#96496)
Route success JSON reads through readProviderJsonResponse (16 MiB cap) in
azure-speech, elevenlabs, microsoft, minimax/tts, xai/stt, and
openrouter/media-understanding to prevent OOM from oversized or hostile
endpoint responses. Mirrors the response-limit campaign already applied to
other provider paths.

AI-assisted.

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 66e2fcc6f8)
2026-08-06 18:51:34 +08:00
mushuiyu886 393c7fe6cd fix(openrouter): bound video catalog JSON reads (#96505)
(cherry picked from commit 5715b55000)
2026-08-06 18:51:34 +08:00
Alix-007 42c6e7869e fix(github-copilot): bound usage response (#96607)
The Copilot usage read in extensions/github-copilot/usage.ts parsed its
HTTP response with an unbounded await res.json(). A hostile or buggy
api.github.com proxy (the proxy endpoint is derived from a user-supplied
token) could stream an unbounded JSON body and drive the usage snapshot
into OOM.

Route the read through the shared readProviderJsonResponse (from
openclaw/plugin-sdk/provider-http), which enforces the 16 MiB byte cap,
cancels the stream on overflow, and wraps malformed JSON with the caller
label. Same no-helper-import-to-bounded-reader shape as the #96027 /
#96038 response-limit work.

Add a focused regression test: when the usage stream exceeds the JSON
byte cap, fetchCopilotUsage rejects with a bounded-overflow error and the
reader cancels the body mid-flight instead of buffering the full
advertised stream. Existing parse/HTTP-error cases keep passing.

(cherry picked from commit 646e54ae35)
2026-08-06 18:51:34 +08:00
Alix-007 a02466e40e fix(voyage): bound embedding-batch status, error, and non-OK responses (#96608)
The batch status read (fetchVoyageBatchStatus) parsed its response with an
unbounded await res.json(), and the batch error-file read (readVoyageBatchError)
buffered the whole body via await res.text(). On top of that, the non-OK
(4xx/5xx) diagnostic body was still read unbounded: assertVoyageResponseOk did
await res.text() before throwing, and the non-OK output-file branch in
runVoyageEmbeddingBatches did the same. Voyage base URLs are user-supplied and
reachable via SSRF, so a misbehaving or hostile endpoint could stream an
unbounded body into memory on any of these paths before parsing.

Route the status JSON through the shared readProviderJsonResponse, the error
file through readResponseWithLimit, and now the non-OK diagnostic body through
readResponseWithLimit as well, all under a single 16 MiB cap, cancelling the
stream on overflow before decode/parse. assertVoyageResponseOk preserves its
original "${context}: ${status} ${text}" diagnostic shape for under-cap bodies
and throws a bounded "(error body exceeds <N> bytes)" on overflow; the non-OK
output-file branch now reuses it instead of a duplicate unbounded read. The
existing error-file fail-soft handling (formatUnavailableBatchError) is
preserved, so a capped endpoint degrades gracefully. The submit path already
bounds its body via postJsonWithRetry/maxResponseBytes and is left untouched.

Symmetric counterpart to the #96027/#96038 response-limit campaign.

(cherry picked from commit d3620da3e0)
2026-08-06 18:51:34 +08:00
Alix-007 3b5fd979fa fix(byteplus): bound video-generation success response (#96606)
(cherry picked from commit 7b5ee739eb)
2026-08-06 18:51:34 +08:00