Commit Graph

62487 Commits

Author SHA1 Message Date
pick-cat f42d5bf2c1 fix(synology-chat): bound user_list fetches with a wall-clock deadline (#109111)
* fix(synology-chat): bound user_list fetches with a wall-clock deadline

* refactor(synology-chat): keep deadline internal

* style(synology-chat): format deadline proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit f7cc0ef838)
2026-08-06 18:55:39 +08:00
maweibin 8e725fc8ab fix(auto-reply): treat U+2028/U+2029 as paragraph boundaries when chunking (#103518)
* fix(auto-reply): treat U+2028/U+2029 as paragraph boundaries when chunking

chunkByParagraph normalized only CR/CRLF before blank-line paragraph detection,
so model output using Unicode LINE/PARAGRAPH SEPARATOR (U+2028/U+2029) instead
of a blank line was not split at those boundaries and fell back to length-based
splitting. Normalize U+2028/U+2029 to \n alongside CR/CRLF, matching how the
Control UI markdown renderer handles them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(auto-reply): normalize U+2028 as line break, U+2029 as blank-line paragraph boundary

Distinguish U+2028 (LINE SEPARATOR) from U+2029 (PARAGRAPH SEPARATOR):
U+2029 becomes \n\n (blank line — paragraph boundary) while U+2028
becomes \n (single newline — intra-paragraph line break).

The original fix mapped both to \n, so standalone U+2029 still
produced single-line text without a blank-line gap — paragraph
detection failed. The combined U+2028
 input accidentally
produced the right blank-line sequence, which masked the bug.

Adds individual tests for lone U+2029 (splits at paragraph boundary),
lone U+2028 (stays within paragraph), and consecutive U+2028

(combined blank line — matches \n\n behavior).

* test(auto-reply): simplify Unicode separator cases

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 3a4e2ef65f)
2026-08-06 18:55:39 +08:00
chengzhichao-xydt 033a660168 fix(discord): honor caller abortSignal during 429 retry backoff (#109913)
* fix(discord): honor caller abortSignal during 429 retry backoff

* test(discord): prove 429 backoff abort through a real loopback server

* test(discord): make retry abort proof deterministic

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 40acbb05c9)
2026-08-06 18:55:39 +08:00
Monkey-wusky 959ee3ee45 fix(msteams): cancel non-OK consent upload response body before throwing (#109701)
* fix(msteams): cancel non-OK consent upload response body before throwing

* fix(msteams): release all consent upload responses

Cancel unread response bodies after successful uploads as well as failed uploads, and fold the lifecycle assertions into the existing status-path tests.

Co-authored-by: Monkey-wusky <66244686+Monkey-wusky@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 9b238a7927)
2026-08-06 18:55:39 +08:00
Wynne668 eab4841bfd fix(lmstudio): cancel model discovery response body on non-ok (#109718)
* fix(lmstudio): cancel model discovery response body on non-ok

Wire the direct-fetch release hook to cancel unread bodies so failed
model discovery releases the TCP connection instead of leaving it open.

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

* refactor(lmstudio): unify response cleanup

Co-authored-by: Zeng Wen <27948732+ZengWen-DT@users.noreply.github.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Zeng Wen <27948732+ZengWen-DT@users.noreply.github.com>
(cherry picked from commit 1573c78f5b)
2026-08-06 18:55:16 +08:00
pick-cat 8b12479826 fix(proxy-capture): guard body-less arrayBuffer reads against oversized responses (#101268)
* fix(proxy-capture): guard body-less arrayBuffer reads against oversized responses

* fix(proxy-capture): exercise body-less fallback in bounded read tests

New tests use mock clones with body: null plus arrayBuffer spies to
prove the content-length precheck guards the !body path. A real
Response clone exposes body.getReader in Node 24, so the prior test
only exercised the streaming branch and would stay green even if
the precheck were deleted.

* chore: retrigger CI

* fix(proxy-capture): reject non-safe content-length before arrayBuffer (#101268)

ClawSweeper P2: the body-less fallback used Number(content-length), so a
huge digit-only Content-Length value could overflow to Infinity, bypass the
Number.isFinite guard, and still call arrayBuffer() — leaving an OOM path in
the hardening PR.

Add declaredContentLengthExceedsCap, which accepts only plain digit strings,
treats any value longer than Number.MAX_SAFE_INTEGER as oversized, and
compares safe-integer parsed values against the cap. Non-numeric or malformed
values fall through to the post-read length check.

Adds a regression test for a 100-digit Content-Length that would previously
have bypassed the guard.

* fix(proxy-capture): normalize zero-padded Content-Length before digit-count guard

* fix(proxy-capture): fail closed without response streams

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 7cde0ac8c0)
2026-08-06 18:55:16 +08:00
RileyJJY 5b460dbbce fix(qqbot): bound tail log reads to actual bytes returned by fs.readSync (#108955)
* fix(qqbot): bound tail log reads to actual bytes returned by fs.readSync

* fix(qqbot): satisfy knip deadcode check for testing export

Add __testing re-export and test-api.ts barrel so knip traces the testing export through a recognized entry point.

* fix(qqbot): restore testing export alongside __testing re-export

Both exports are needed: testing for proof scripts, __testing for knip tracing.

* fix(qqbot): remove unused __testing re-export from log-helpers

test-api.ts already imports testing and re-exports as __testing. The extra re-export in log-helpers.ts was unused by production code.

* fix(qqbot): retry short log tail reads

* test(qqbot): keep short-read seam private

Co-authored-by: RileyJJY <100176083+RileyJJY@users.noreply.github.com>

* test(qqbot): exercise short reads through log export

Co-authored-by: RileyJJY <0668000974@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: RileyJJY <100176083+RileyJJY@users.noreply.github.com>
(cherry picked from commit 3f89aae98d)
2026-08-06 18:54:54 +08:00
thomas.szbay 5400d5bedf fix(agents): bound base64 image input before decode in tool-image sanitizer (#105086)
* fix(agents): bound base64 image input before decode in tool-image sanitizer

* fix(agents): lower input-size cap to 10MB for OOM headroom

* fix(agents): align tool-image input-cap comment with 10 MiB ceiling

* fix(agents): typecheck-safe access in tool-image input-cap test

* test(agents): exercise real tool image input cap

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit b85531c62f)
2026-08-06 18:54:54 +08:00
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