mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
* fix(cli): reject malformed hosted shell Unicode before admission Prevent lone UTF-16 surrogates from reaching Workspace acquisition or execution while preserving valid Unicode and durable history. - Refuse whole batches before Hooks and native tool admission - Stop malformed sequential Hook rewrites and restore safe refusals - Suppress post-tool callbacks for live and replayed Unicode refusals - Cover local/O2 persistence, same-turn correction, and Session reuse - Document the admission design and local acceptance evidence * fix(cli): preserve durable hosted shell Unicode refusals Keep malformed Shell input refusals bounded and recoverable after Hook rewrites without losing policy denials or the original store error. - Normalize optional arguments and validate reduced refusal evidence - Fold nested permission rewrites and bound assembled Hook receipts - Read recovery resources concurrently while preserving event order - Cover MCP and background guards, sibling denials and failed writes - Stabilize Hook admission waits and verify the second Session alone * fix(cli): keep hosted Unicode refusals replayable and batch-wide Keep durable Unicode refusals correctable across terminal Hook recovery and bounded receipts, without admitting sibling tools. - Accept proven-unstarted Hooks while rejecting blocked evidence - Preserve a fixed Unicode reason in byte-bounded Hook refusals - Retain each sibling's own argument validation error - Pin MCP admission, Hook handoff and continuation regression cases * fix(cli): recover cancelled size-refused hook plans Treat cancelled Hook plans as terminal when their durable evidence proves a result or no dispatch, so Unicode batch refusals can replay. - Preserve failure-closed checks for unresolved or contradictory evidence - Cover bounded permission refusals and independent recovery guard failures - Assert Java capture lanes and single successful dispatch in both sessions * test(sdk-java): scope Unicode publication checks per session Shared publication rows made the local gate depend on invocation order. A global positive count also hid a missing secondary-session capture. - Filter publication counts by the current tenant and each session - Preserve local zero and o2 positive checks for both sessions * test(sdk-java): verify hosted Unicode capture completion Make local publication checks run against an available service, and distinguish completed o2 captures from reservation rows. - Register publication fixtures for both capture modes - Require referenced and complete results in each o2 session * test(sdk-java): align Unicode gate with managed schema Keep the hosted Unicode oracle runnable after schema consolidation. Use canonical tables without changing the per-session completion and single-dispatch assertions. - Query captures from ma_output_capture - Query dispatch evidence from ma_tool_execution * test(managed-agent): align Unicode gate with main contracts Keep the hosted Unicode gate compatible with the server's updated Checkstyle rules and object-store contract after the module move. - Add braces around the missing-object fixture refusal - Add braces around the local-mode empty-capture assertion - Align the fixture with the current object-store validation method * test(managed-agent): register native macOS workspace fixtures The Hosted tool-turn fixture registered guarded workspaces only on Linux, leaving corrected Shell calls unavailable on supported macOS hosts after malformed input had been refused. - Match fixture registration to the native storage guard platforms - Exercise the existing physical checks for both supported host systems Native macOS local/O2 tests and the non-Unicode workspace control pass with the original assertions, physical guards and execution deadlines. --------- Co-authored-by: wangheyang <[email protected]>
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2026 Qwen Team
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import type { ServerResponse } from 'node:http';
|
|
|
|
// The Hosted drivers' Node proxies buffer the body fetch decoded and send it
|
|
// on, so only headers that still describe that body may follow it. Hop-by-hop
|
|
// fields (RFC 9110 §7.6.1, the proxy-auth pair, and every name the upstream
|
|
// `Connection` lists) describe Spring's connection: relaying its
|
|
// `Keep-Alive: timeout=60` let the daemon's fetch pool reuse a socket the
|
|
// proxy had just closed at its own 5 s idle timeout ("other side closed").
|
|
// Framing and coding fields describe bytes the proxy no longer holds; Node
|
|
// frames the buffered body itself.
|
|
const NOT_RELAYED = [
|
|
'connection',
|
|
'keep-alive',
|
|
'proxy-authenticate',
|
|
'proxy-authorization',
|
|
'proxy-connection',
|
|
'te',
|
|
'transfer-encoding',
|
|
'upgrade',
|
|
'trailer',
|
|
'content-length',
|
|
'content-encoding',
|
|
];
|
|
|
|
export function relayedHeaders(headers: Headers): Record<string, string> {
|
|
const dropped = new Set([
|
|
...NOT_RELAYED,
|
|
...(headers.get('connection') ?? '')
|
|
.split(',')
|
|
.map((name) => name.trim().toLowerCase())
|
|
.filter(Boolean),
|
|
]);
|
|
return Object.fromEntries(
|
|
[...headers].filter(([name]) => !dropped.has(name)),
|
|
);
|
|
}
|
|
|
|
// The wholesale upstream relays — hosted-{latency,process-crash,
|
|
// shell-output,shell-unicode,store-failure,workspace-tool-turn,channel-fault}-driver.ts —
|
|
// pass through this one site, pinned by the caller list in
|
|
// hosted-relay-headers.test.ts. The drivers' other upstream replies write
|
|
// fixed header literals and must stay that way: a driver-local copy of the
|
|
// upstream header set would leak hop-by-hop spellings again, and nothing
|
|
// enforces it.
|
|
export function relayUpstream(
|
|
res: ServerResponse,
|
|
upstream: Response,
|
|
body: Buffer,
|
|
): void {
|
|
res.writeHead(upstream.status, relayedHeaders(upstream.headers));
|
|
res.end(body);
|
|
}
|