From caf8456864fbef9f6e35cf1fc978e83c41d760bd Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Wed, 17 May 2023 18:47:12 -0300 Subject: [PATCH] fix: adjust feature flags, wrong zip usage (#367) --- examples/api/src-tauri/Cargo.toml | 2 +- examples/api/src-tauri/tauri.conf.json | 74 +++++------ plugins/dialog/src/init.js | 16 +-- plugins/http/Cargo.toml | 2 +- plugins/http/guest-js/index.ts | 2 +- plugins/http/src/commands/client.rs | 2 +- plugins/shell/src/init.js | 49 ++++--- plugins/updater/Cargo.toml | 2 + plugins/updater/src/error.rs | 4 + plugins/updater/src/updater/extract.rs | 124 ++++++++++-------- plugins/window/guest-js/index.ts | 2 +- plugins/window/src/scripts/drag.js | 14 +- plugins/window/src/scripts/print.js | 4 +- plugins/window/src/scripts/toggle-devtools.js | 24 ++-- 14 files changed, 167 insertions(+), 154 deletions(-) diff --git a/examples/api/src-tauri/Cargo.toml b/examples/api/src-tauri/Cargo.toml index 9620af9a..489ea2ed 100644 --- a/examples/api/src-tauri/Cargo.toml +++ b/examples/api/src-tauri/Cargo.toml @@ -22,7 +22,7 @@ tauri-plugin-log = { path = "../../../plugins/log" } tauri-plugin-fs = { path = "../../../plugins/fs" } tauri-plugin-clipboard = { path = "../../../plugins/clipboard" } tauri-plugin-dialog = { path = "../../../plugins/dialog" } -tauri-plugin-http = { path = "../../../plugins/http", features = [ "http-multipart" ] } +tauri-plugin-http = { path = "../../../plugins/http", features = [ "multipart" ] } tauri-plugin-notification = { path = "../../../plugins/notification", features = [ "windows7-compat" ] } tauri-plugin-os = { path = "../../../plugins/os" } tauri-plugin-process = { path = "../../../plugins/process" } diff --git a/examples/api/src-tauri/tauri.conf.json b/examples/api/src-tauri/tauri.conf.json index 8fd3fee4..6f5f422d 100644 --- a/examples/api/src-tauri/tauri.conf.json +++ b/examples/api/src-tauri/tauri.conf.json @@ -48,44 +48,44 @@ } }, "fs": { - "scope": { - "allow": ["$APPDATA/db/**", "$DOWNLOAD/**", "$RESOURCE/**"], - "deny": ["$APPDATA/db/*.stronghold"] - } - }, - "shell": { - "open": true, - "scope": [ - { - "name": "sh", - "cmd": "sh", - "args": [ - "-c", - { - "validator": "\\S+" - } - ] - }, - { - "name": "cmd", - "cmd": "cmd", - "args": [ - "/C", - { - "validator": "\\S+" - } - ] - } - ] - }, - "http": { - "scope": ["http://localhost:3003"] - }, - "updater": { - "endpoints": [ - "https://tauri-update-server.vercel.app/update/{{target}}/{{current_version}}" - ] + "scope": { + "allow": ["$APPDATA/db/**", "$DOWNLOAD/**", "$RESOURCE/**"], + "deny": ["$APPDATA/db/*.stronghold"] } + }, + "shell": { + "open": true, + "scope": [ + { + "name": "sh", + "cmd": "sh", + "args": [ + "-c", + { + "validator": "\\S+" + } + ] + }, + { + "name": "cmd", + "cmd": "cmd", + "args": [ + "/C", + { + "validator": "\\S+" + } + ] + } + ] + }, + "http": { + "scope": ["http://localhost:3003"] + }, + "updater": { + "endpoints": [ + "https://tauri-update-server.vercel.app/update/{{target}}/{{current_version}}" + ] + } }, "tauri": { "pattern": { diff --git a/plugins/dialog/src/init.js b/plugins/dialog/src/init.js index 79c9fd8b..62d0b82c 100644 --- a/plugins/dialog/src/init.js +++ b/plugins/dialog/src/init.js @@ -3,13 +3,13 @@ // SPDX-License-Identifier: MIT window.alert = function (message) { - window.__TAURI_INVOKE__('plugin:dialog|message', { - message: message.toString() - }) -} + window.__TAURI_INVOKE__("plugin:dialog|message", { + message: message.toString(), + }); +}; window.confirm = function (message) { - return window.__TAURI_INVOKE__('plugin:dialog|confirm', { - message: message.toString() - }) -} + return window.__TAURI_INVOKE__("plugin:dialog|confirm", { + message: message.toString(), + }); +}; diff --git a/plugins/http/Cargo.toml b/plugins/http/Cargo.toml index b0e6ab32..faf4371f 100644 --- a/plugins/http/Cargo.toml +++ b/plugins/http/Cargo.toml @@ -19,7 +19,7 @@ http = "0.2" reqwest = { version = "0.11", default-features = false, features = [ "json", "stream" ] } [features] -http-multipart = [ "reqwest/multipart" ] +multipart = [ "reqwest/multipart" ] native-tls = [ "reqwest/native-tls" ] native-tls-vendored = [ "reqwest/native-tls-vendored" ] rustls-tls = [ "reqwest/rustls-tls" ] diff --git a/plugins/http/guest-js/index.ts b/plugins/http/guest-js/index.ts index 47e5e323..6efb45b6 100644 --- a/plugins/http/guest-js/index.ts +++ b/plugins/http/guest-js/index.ts @@ -103,7 +103,7 @@ class Body { * and the value is either a string or a file object. * * By default it sets the `application/x-www-form-urlencoded` Content-Type header, - * but you can set it to `multipart/form-data` if the Cargo feature `http-multipart` is enabled. + * but you can set it to `multipart/form-data` if the Cargo feature `multipart` is enabled. * * Note that a file path must be allowed in the `fs` allowlist scope. * @example diff --git a/plugins/http/src/commands/client.rs b/plugins/http/src/commands/client.rs index 2b7131a7..997dee05 100644 --- a/plugins/http/src/commands/client.rs +++ b/plugins/http/src/commands/client.rs @@ -91,7 +91,7 @@ impl Client { headers: &mut Option, form_body: FormBody, ) -> crate::Result { - #[cfg(feature = "http-multipart")] + #[cfg(feature = "multipart")] if matches!( headers .as_ref() diff --git a/plugins/shell/src/init.js b/plugins/shell/src/init.js index c43f7cdf..61cbe3b4 100644 --- a/plugins/shell/src/init.js +++ b/plugins/shell/src/init.js @@ -2,39 +2,38 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -;(function () { +(function () { // open links with the API function openLinks() { - document.querySelector('body').addEventListener( - 'click', - function (e) { - var target = e.target - while (target != null) { - if (target.matches('a')) { - if ( - target.href && - (['http://', 'https://', 'mailto:', 'tel:'].some(v => target.href.startsWith(v))) && - target.target === '_blank' - ) { - window.__TAURI_INVOKE__('plugin:shell|open', { - path: target.href - }) - e.preventDefault() - } - break + document.querySelector("body").addEventListener("click", function (e) { + var target = e.target; + while (target != null) { + if (target.matches("a")) { + if ( + target.href && + ["http://", "https://", "mailto:", "tel:"].some((v) => + target.href.startsWith(v) + ) && + target.target === "_blank" + ) { + window.__TAURI_INVOKE__("plugin:shell|open", { + path: target.href, + }); + e.preventDefault(); } - target = target.parentElement + break; } + target = target.parentElement; } - ) + }); } if ( - document.readyState === 'complete' || - document.readyState === 'interactive' + document.readyState === "complete" || + document.readyState === "interactive" ) { - openLinks() + openLinks(); } else { - window.addEventListener('DOMContentLoaded', openLinks, true) + window.addEventListener("DOMContentLoaded", openLinks, true); } -})() +})(); diff --git a/plugins/updater/Cargo.toml b/plugins/updater/Cargo.toml index 33e726ac..d4f036fa 100644 --- a/plugins/updater/Cargo.toml +++ b/plugins/updater/Cargo.toml @@ -26,6 +26,8 @@ tempfile = "3" flate2 = "1" tar = "0.4" ignore = "0.4" + +[target."cfg(target_os = \"windows\")".dependencies] zip = { version = "0.6", default-features = false } [dev-dependencies] diff --git a/plugins/updater/src/error.rs b/plugins/updater/src/error.rs index 8f0b9c74..20f2eb42 100644 --- a/plugins/updater/src/error.rs +++ b/plugins/updater/src/error.rs @@ -84,6 +84,10 @@ pub enum Error { /// Ignore error. #[error("failed to walkdir: {0}")] Ignore(#[from] ignore::Error), + /// Zip error. + #[cfg(windows)] + #[error(transparent)] + ZipError(#[from] zip::result::ZipError), } impl Serialize for Error { diff --git a/plugins/updater/src/updater/extract.rs b/plugins/updater/src/updater/extract.rs index 143c4d3f..4d0feca6 100644 --- a/plugins/updater/src/updater/extract.rs +++ b/plugins/updater/src/updater/extract.rs @@ -5,8 +5,8 @@ use std::{ borrow::Cow, fs, - io::{self, Cursor, Read, Seek}, - path::{self, Path, PathBuf}, + io::{self, Read, Seek}, + path::{self, Path}, }; use crate::{Error, Result}; @@ -46,10 +46,20 @@ pub enum ArchiveFormat { /// Tar archive. Tar(Option), /// Zip archive. - #[allow(dead_code)] + #[cfg(windows)] Zip, } +impl ArchiveFormat { + fn compression(self) -> Option { + match self { + Self::Tar(c) => c, + #[allow(unreachable_patterns)] + _ => None, + } + } +} + /// The supported compression types. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] @@ -59,8 +69,9 @@ pub enum Compression { } /// The zip entry. +#[cfg(windows)] pub struct ZipEntry { - path: PathBuf, + path: std::path::PathBuf, is_dir: bool, file_contents: Vec, } @@ -73,7 +84,7 @@ pub enum Entry<'a, R: Read> { Tar(Box>), /// An entry of a zip archive. #[non_exhaustive] - #[allow(dead_code)] + #[cfg(windows)] Zip(ZipEntry), } @@ -82,6 +93,7 @@ impl<'a, R: Read> Entry<'a, R> { pub fn path(&self) -> Result> { match self { Self::Tar(e) => e.path().map_err(Into::into), + #[cfg(windows)] Self::Zip(e) => Ok(Cow::Borrowed(&e.path)), } } @@ -113,6 +125,7 @@ impl<'a, R: Read> Entry<'a, R> { } } } + #[cfg(windows)] Self::Zip(entry) => { if entry.is_dir { // this is a directory, lets create it @@ -126,7 +139,10 @@ impl<'a, R: Read> Entry<'a, R> { } } else { let mut out_file = fs::File::create(into_path)?; - io::copy(&mut Cursor::new(entry.file_contents), &mut out_file)?; + io::copy( + &mut std::io::Cursor::new(entry.file_contents), + &mut out_file, + )?; } } } @@ -158,11 +174,7 @@ impl<'a, R: Read + Seek> Extract<'a, R> { #[cfg(debug_assertions)] eprintln!("Could not seek to start of the file"); } - let compression = if let ArchiveFormat::Tar(compression) = archive_format { - compression - } else { - None - }; + let compression = archive_format.compression(); Extract { reader: match compression { Some(Compression::Gz) => { @@ -198,28 +210,26 @@ impl<'a, R: Read + Seek> Extract<'a, R> { } } + #[cfg(windows)] ArchiveFormat::Zip => { - #[cfg(feature = "fs-extract-api")] - { - let mut archive = zip::ZipArchive::new(self.reader.get_mut())?; - let file_names = archive - .file_names() - .map(|f| f.to_string()) - .collect::>(); - for path in file_names { - let mut zip_file = archive.by_name(&path)?; - let is_dir = zip_file.is_dir(); - let mut file_contents = Vec::new(); - zip_file.read_to_end(&mut file_contents)?; - let stop = f(Entry::Zip(ZipEntry { - path: path.into(), - is_dir, - file_contents, - })) - .map_err(Into::into)?; - if stop { - break; - } + let mut archive = zip::ZipArchive::new(self.reader.get_mut())?; + let file_names = archive + .file_names() + .map(|f| f.to_string()) + .collect::>(); + for path in file_names { + let mut zip_file = archive.by_name(&path)?; + let is_dir = zip_file.is_dir(); + let mut file_contents = Vec::new(); + zip_file.read_to_end(&mut file_contents)?; + let stop = f(Entry::Zip(ZipEntry { + path: path.into(), + is_dir, + file_contents, + })) + .map_err(Into::into)?; + if stop { + break; } } } @@ -239,34 +249,32 @@ impl<'a, R: Read + Seek> Extract<'a, R> { archive.unpack(into_dir)?; } + #[cfg(windows)] ArchiveFormat::Zip => { - #[cfg(feature = "fs-extract-api")] - { - let mut archive = zip::ZipArchive::new(self.reader.get_mut())?; - for i in 0..archive.len() { - let mut file = archive.by_index(i)?; - // Decode the file name from raw bytes instead of using file.name() directly. - // file.name() uses String::from_utf8_lossy() which may return messy characters - // such as: 爱交易.app/, that does not work as expected. - // Here we require the file name must be a valid UTF-8. - let file_name = String::from_utf8(file.name_raw().to_vec())?; - let out_path = into_dir.join(file_name); - if file.is_dir() { - fs::create_dir_all(&out_path)?; - } else { - if let Some(out_path_parent) = out_path.parent() { - fs::create_dir_all(out_path_parent)?; - } - let mut out_file = fs::File::create(&out_path)?; - io::copy(&mut file, &mut out_file)?; + let mut archive = zip::ZipArchive::new(self.reader.get_mut())?; + for i in 0..archive.len() { + let mut file = archive.by_index(i)?; + // Decode the file name from raw bytes instead of using file.name() directly. + // file.name() uses String::from_utf8_lossy() which may return messy characters + // such as: 爱交易.app/, that does not work as expected. + // Here we require the file name must be a valid UTF-8. + let file_name = String::from_utf8(file.name_raw().to_vec())?; + let out_path = into_dir.join(file_name); + if file.is_dir() { + fs::create_dir_all(&out_path)?; + } else { + if let Some(out_path_parent) = out_path.parent() { + fs::create_dir_all(out_path_parent)?; } - // Get and Set permissions - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - if let Some(mode) = file.unix_mode() { - fs::set_permissions(&out_path, fs::Permissions::from_mode(mode))?; - } + let mut out_file = fs::File::create(&out_path)?; + io::copy(&mut file, &mut out_file)?; + } + // Get and Set permissions + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + if let Some(mode) = file.unix_mode() { + fs::set_permissions(&out_path, fs::Permissions::from_mode(mode))?; } } } diff --git a/plugins/window/guest-js/index.ts b/plugins/window/guest-js/index.ts index 59e7f77a..6a3a1585 100644 --- a/plugins/window/guest-js/index.ts +++ b/plugins/window/guest-js/index.ts @@ -319,7 +319,7 @@ class WebviewWindowHandle { /** The window label. It is a unique identifier for the window, can be used to reference it later. */ label: WindowLabel; /** Local event listeners. */ - listeners: Record>>; + listeners: Record>>; constructor(label: WindowLabel) { this.label = label; diff --git a/plugins/window/src/scripts/drag.js b/plugins/window/src/scripts/drag.js index b8abeb2c..3b227bc6 100644 --- a/plugins/window/src/scripts/drag.js +++ b/plugins/window/src/scripts/drag.js @@ -2,16 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -document.addEventListener('mousedown', (e) => { - if (e.target.hasAttribute('data-tauri-drag-region') && e.buttons === 1) { +document.addEventListener("mousedown", (e) => { + if (e.target.hasAttribute("data-tauri-drag-region") && e.buttons === 1) { // prevents text cursor - e.preventDefault() + e.preventDefault(); // fix #2549: double click on drag region edge causes content to maximize without window sizing change // https://github.com/tauri-apps/tauri/issues/2549#issuecomment-1250036908 - e.stopImmediatePropagation() + e.stopImmediatePropagation(); // start dragging if the element has a `tauri-drag-region` data attribute and maximize on double-clicking it - const cmd = e.detail === 2 ? 'internal_toggle_maximize' : 'start_dragging' - window.__TAURI_INVOKE__('plugin:window|' + cmd) + const cmd = e.detail === 2 ? "internal_toggle_maximize" : "start_dragging"; + window.__TAURI_INVOKE__("plugin:window|" + cmd); } -}) +}); diff --git a/plugins/window/src/scripts/print.js b/plugins/window/src/scripts/print.js index 2be2e491..1e833766 100644 --- a/plugins/window/src/scripts/print.js +++ b/plugins/window/src/scripts/print.js @@ -3,5 +3,5 @@ // SPDX-License-Identifier: MIT window.print = function () { - return window.__TAURI_INVOKE__('plugin:window|print') -} + return window.__TAURI_INVOKE__("plugin:window|print"); +}; diff --git a/plugins/window/src/scripts/toggle-devtools.js b/plugins/window/src/scripts/toggle-devtools.js index 2bff9d12..42c4bdba 100644 --- a/plugins/window/src/scripts/toggle-devtools.js +++ b/plugins/window/src/scripts/toggle-devtools.js @@ -2,25 +2,25 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -;(function () { +(function () { function toggleDevtoolsHotkey() { - const isHotkey = navigator.appVersion.includes('Mac') - ? event => event.metaKey && event.altKey && event.key === 'I' - : event => event.ctrlKey && event.shiftKey && event.key === 'I' + const isHotkey = navigator.appVersion.includes("Mac") + ? (event) => event.metaKey && event.altKey && event.key === "I" + : (event) => event.ctrlKey && event.shiftKey && event.key === "I"; - document.addEventListener('keydown', event => { + document.addEventListener("keydown", (event) => { if (isHotkey(event)) { - window.__TAURI_INVOKE__('plugin:window|internal_toggle_devtools'); + window.__TAURI_INVOKE__("plugin:window|internal_toggle_devtools"); } - }) + }); } if ( - document.readyState === 'complete' || - document.readyState === 'interactive' + document.readyState === "complete" || + document.readyState === "interactive" ) { - toggleDevtoolsHotkey() + toggleDevtoolsHotkey(); } else { - window.addEventListener('DOMContentLoaded', toggleDevtoolsHotkey, true) + window.addEventListener("DOMContentLoaded", toggleDevtoolsHotkey, true); } -})() +})();