增加 Responses 槽位安全保险丝

拒绝超出 4096 的 output_index,避免异常上游输入触发巨额扩容

补充安全边界测试且不限制正常输出内容
This commit is contained in:
2026-09-12 07:17:16 +00:00
parent 16a6cdaf79
commit 74fad546ff
+25 -2
View File
@@ -2276,7 +2276,7 @@ where
accumulation.responses_output = output;
}
for (slot, item) in output_items {
upsert_responses_output_item(&mut accumulation.responses_output, slot, item);
upsert_responses_output_item(&mut accumulation.responses_output, slot, item)?;
}
if is_completion {
@@ -3744,12 +3744,19 @@ fn upsert_responses_output_item(
output: &mut Vec<serde_json::Value>,
slot: u64,
item: serde_json::Value,
) {
) -> Result<(), LlmError> {
const MAX_RESPONSES_OUTPUT_SLOT: u64 = 4096;
if slot >= MAX_RESPONSES_OUTPUT_SLOT {
return Err(LlmError::Deserialize(format!(
"解析 LLM Responses SSE 事件失败:output_index 超出安全上限({slot} >= {MAX_RESPONSES_OUTPUT_SLOT}"
)));
}
let index = slot as usize;
if index >= output.len() {
output.resize(index + 1, serde_json::Value::Null);
}
output[index] = item;
Ok(())
}
fn patch_responses_output_arguments(output: &mut [serde_json::Value], slot: u64, arguments: &str) {
@@ -4103,6 +4110,22 @@ mod tests {
use super::*;
#[test]
fn responses_output_slot_safety_fuse_rejects_only_out_of_range_indices() {
let mut output = Vec::new();
upsert_responses_output_item(&mut output, 4095, serde_json::json!({"type": "message"}))
.expect("slot below the safety fuse should be accepted");
assert_eq!(output.len(), 4096);
let error =
upsert_responses_output_item(&mut output, 4096, serde_json::json!({"type": "message"}))
.expect_err("slot at the safety fuse should be rejected");
assert!(
matches!(error, LlmError::Deserialize(message) if message.contains("output_index"))
);
assert_eq!(output.len(), 4096);
}
#[test]
fn llm_error_kind_is_stable_for_adapter_mapping() {
assert_eq!(