fix: 审计后续 3 项修复 — 残留清理 + FTS5 CJK + HTTP 大小限制
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
1. Shell Hands 残留清理 (3处): - message.rs: 移除过时的 zclaw_hands::slideshow 注释 - user_profiler.rs: slideshow 偏好改为 RecentTopic - handStore.test.ts: 移除 speech mock 数据 (3→2) 2. zclaw-growth FTS5 CJK 查询修复: - sanitize_fts_query CJK 路径从精确短语改为 token OR 组合 - "Rust 编程" → "rust" OR "编程" (之前是 "rust 编程" 精确匹配) - 修复 test_memory_lifecycle + test_semantic_search_ranking 3. WASM HTTP 响应大小限制: - Content-Length 预检 + 读取后截断 (1MB 上限) - read_to_string 改为显式错误处理 651 测试全通过,0 失败。
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use serde_json::Value;
|
||||
use std::io::Read as IoRead;
|
||||
use std::path::PathBuf;
|
||||
use tracing::{debug, warn};
|
||||
use wasmtime::*;
|
||||
@@ -23,6 +24,9 @@ use crate::{Skill, SkillContext, SkillManifest, SkillResult};
|
||||
/// Maximum WASM binary size (10 MB).
|
||||
const MAX_WASM_SIZE: usize = 10 * 1024 * 1024;
|
||||
|
||||
/// Maximum HTTP response body size for host function (1 MB).
|
||||
const MAX_HTTP_RESPONSE_SIZE: usize = 1024 * 1024;
|
||||
|
||||
/// Fuel per second of CPU time (heuristic: ~10M instructions/sec).
|
||||
const FUEL_PER_SEC: u64 = 10_000_000;
|
||||
|
||||
@@ -318,8 +322,31 @@ fn add_host_functions(linker: &mut Linker<WasiP1Ctx>, network_allowed: bool) ->
|
||||
|
||||
match response {
|
||||
Ok(mut resp) => {
|
||||
let body = resp.body_mut().read_to_string().unwrap_or_default();
|
||||
write_guest_bytes(&mut caller, out_ptr, out_cap, body.as_bytes())
|
||||
// Enforce response size limit before reading body
|
||||
let content_length = resp.header("content-length")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.and_then(|v| v.parse::<usize>().ok());
|
||||
if let Some(len) = content_length {
|
||||
if len > MAX_HTTP_RESPONSE_SIZE {
|
||||
warn!("[WasmSkill] http_fetch denied — response too large: {} bytes (max {})", len, MAX_HTTP_RESPONSE_SIZE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
let mut body = String::new();
|
||||
match resp.body_mut().read_to_string(&mut body) {
|
||||
Ok(_) => {
|
||||
if body.len() > MAX_HTTP_RESPONSE_SIZE {
|
||||
warn!("[WasmSkill] http_fetch — response exceeded limit after read, truncating");
|
||||
body.truncate(MAX_HTTP_RESPONSE_SIZE);
|
||||
}
|
||||
write_guest_bytes(&mut caller, out_ptr, out_cap, body.as_bytes())
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("[WasmSkill] http_fetch body read error: {}", e);
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("[WasmSkill] http_fetch error for {}: {}", url, e);
|
||||
|
||||
Reference in New Issue
Block a user