From 6ded19d018af763dae2ce40df784a25b258a43a0 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 20 Jun 2026 12:32:45 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=81=E5=AE=9A=E6=A1=8C=E9=9D=A2=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 桌面文件导出路径转换失败转为稳定不可用响应 桌面文件导入路径转换失败转为稳定不可用响应 桌面壳配置检查禁止暴露原生路径错误 --- apps/desktop-shell/scripts/check-config.mjs | 14 ++++++++++++++ .../src-tauri/src/host_bridge/files.rs | 14 +++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/desktop-shell/scripts/check-config.mjs b/apps/desktop-shell/scripts/check-config.mjs index 774e8fe1c..07cc4e252 100644 --- a/apps/desktop-shell/scripts/check-config.mjs +++ b/apps/desktop-shell/scripts/check-config.mjs @@ -1086,6 +1086,20 @@ function assertDesktopDialogBoundary(method, functionName, filterLabel, expected if (fileFunctionBody.includes(blockedDialogAction)) { throw new Error(`desktop shell ${method} must not use ${blockedDialogAction}`); } + const unavailableResponse = + action === 'save' + ? 'Err(_) => return file_export_unavailable_response(request)' + : 'Err(_) => return file_import_unavailable_response(request)'; + if (!fileFunctionBody.includes(unavailableResponse)) { + throw new Error(`desktop shell ${method} must hide native path conversion errors`); + } + if ( + fileFunctionBody.includes( + 'return failed(request.id.clone(), "host_error", error.to_string())', + ) + ) { + throw new Error(`desktop shell ${method} must not expose native path errors`); + } } function assertNoRawHostContextUrl(urlValue, label) { diff --git a/apps/desktop-shell/src-tauri/src/host_bridge/files.rs b/apps/desktop-shell/src-tauri/src/host_bridge/files.rs index c63f15273..a18ce3496 100644 --- a/apps/desktop-shell/src-tauri/src/host_bridge/files.rs +++ b/apps/desktop-shell/src-tauri/src/host_bridge/files.rs @@ -50,7 +50,7 @@ pub(crate) async fn export_desktop_host_bridge_text_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_export_unavailable_response(request), }; let export_result = tauri::async_runtime::spawn_blocking(move || write_export_text_file(path, content)).await; @@ -83,7 +83,7 @@ pub(crate) async fn import_desktop_host_bridge_text_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_import_unavailable_response(request), }; let import_result = tauri::async_runtime::spawn_blocking(move || import_text_file_payload(path)).await; @@ -111,7 +111,7 @@ pub(crate) async fn import_desktop_host_bridge_document_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_import_unavailable_response(request), }; let import_result = tauri::async_runtime::spawn_blocking(move || import_document_file_payload(path)).await; @@ -141,7 +141,7 @@ pub(crate) async fn export_desktop_host_bridge_image_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_export_unavailable_response(request), }; let export_result = tauri::async_runtime::spawn_blocking(move || write_export_bytes_file(path, bytes)).await; @@ -173,7 +173,7 @@ pub(crate) async fn import_desktop_host_bridge_image_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_import_unavailable_response(request), }; let import_result = tauri::async_runtime::spawn_blocking(move || { import_image_file_payload(path, "selected", None) @@ -200,7 +200,7 @@ pub(crate) async fn import_desktop_host_bridge_audio_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_import_unavailable_response(request), }; let import_result = tauri::async_runtime::spawn_blocking(move || import_audio_file_payload(path)).await; @@ -230,7 +230,7 @@ pub(crate) async fn export_desktop_host_bridge_audio_file( }; let path = match file_path.into_path() { Ok(path) => path, - Err(error) => return failed(request.id.clone(), "host_error", error.to_string()), + Err(_) => return file_export_unavailable_response(request), }; let export_result = tauri::async_runtime::spawn_blocking(move || write_export_bytes_file(path, bytes)).await;