From c9d2ed041bfef87024e11383cec32acc69d5970d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 6 Oct 2026 18:49:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=B3=A8=E5=86=8C=E8=A1=A8?= =?UTF-8?q?=E6=8A=8A=E9=9D=9E=20UTF-8=20=E5=86=85=E5=AE=B9=E5=BD=92?= =?UTF-8?q?=E5=85=A5=20malformed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - registry.rs 的 load_or_create 单独处理 ErrorKind::InvalidData,返回 RegistryError::Malformed,不再落进通用 Io 被报成路径/权限故障 - 新增 rejects_non_utf8_content_as_malformed 用例 --- .../src-tauri/src/export/registry.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/apps/ai-game-creator-shell/src-tauri/src/export/registry.rs b/apps/ai-game-creator-shell/src-tauri/src/export/registry.rs index 569758eb9..d7de77b46 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/export/registry.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/export/registry.rs @@ -72,6 +72,14 @@ where write_atomically(path, &created)?; (created, true) } + Err(error) if error.kind() == std::io::ErrorKind::InvalidData => { + // 非 UTF-8 字节就是「内容不是本目标期望的形状」,与 JSON 解析失败同类;落进通用 Io 会 + // 被报成「路径 / 权限故障」,把用户和 agent 往修权限的方向引。 + return Err(RegistryError::Malformed { + path: path.to_path_buf(), + cause: format!("注册表不是有效 UTF-8:{error}"), + }); + } Err(error) => { return Err(RegistryError::Io { path: path.to_path_buf(), @@ -219,6 +227,21 @@ mod tests { assert_eq!(fs::read_to_string(&path).unwrap(), "{ not json"); } + #[test] + fn rejects_non_utf8_content_as_malformed() { + let path = fixture_directory("non-utf8").join("target.json"); + fs::write(&path, [0xff, 0xfe, 0x00]).unwrap(); + let empty = Fixture { + name: String::new(), + }; + + let error = load_or_create(&path, &empty).expect_err("invalid utf-8 must fail closed"); + assert!( + matches!(error, RegistryError::Malformed { .. }), + "非 UTF-8 必须报成 malformed,而不是 host/path 故障:{error:?}" + ); + } + #[test] fn rejects_unknown_fields_so_agent_drift_is_visible() { let path = fixture_directory("unknown").join("target.json");