From 8bf7d514ffff1074780bb0555853aad75566569e Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Sun, 23 Nov 2025 00:18:08 +0100 Subject: [PATCH 01/11] alternative patch method --- crates/tauri-bundler/src/bundle.rs | 45 ++++++------ crates/tauri-bundler/src/bundle/kmp/mod.rs | 54 ++++++++++++++ crates/tauri-bundler/src/bundle/linux/mod.rs | 5 -- crates/tauri-bundler/src/bundle/linux/util.rs | 59 --------------- .../tauri-bundler/src/bundle/windows/mod.rs | 2 - .../tauri-bundler/src/bundle/windows/util.rs | 72 ------------------- crates/tauri-bundler/src/error.rs | 16 +---- crates/tauri-utils/src/platform.rs | 12 ++-- 8 files changed, 88 insertions(+), 177 deletions(-) create mode 100644 crates/tauri-bundler/src/bundle/kmp/mod.rs delete mode 100644 crates/tauri-bundler/src/bundle/linux/util.rs diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index 654ad5647401..79fc3ead18c7 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -4,6 +4,7 @@ // SPDX-License-Identifier: MIT mod category; +mod kmp; #[cfg(target_os = "linux")] mod linux; #[cfg(target_os = "macos")] @@ -15,29 +16,33 @@ mod windows; use tauri_utils::{display_path, platform::Target as TargetPlatform}; +const BUNDLE_VAR_TOKEN: &[u8] = b"__TAURI_BUNDLE_TYPE_VAR_UNK"; /// Patch a binary with bundle type information fn patch_binary(binary: &PathBuf, package_type: &PackageType) -> crate::Result<()> { - match package_type { - #[cfg(target_os = "linux")] - PackageType::AppImage | PackageType::Deb | PackageType::Rpm => { - log::info!( - "Patching binary {:?} for type {}", - binary, - package_type.short_name() - ); - linux::patch_binary(binary, package_type)?; - } - PackageType::Nsis | PackageType::WindowsMsi => { - log::info!( - "Patching binary {:?} for type {}", - binary, - package_type.short_name() - ); - windows::patch_binary(binary, package_type)?; - } - _ => (), - } + let mut file_data = std::fs::read(binary).expect("Could not read binary file."); + + if let Some(bundle_var_index) = kmp::index_of(BUNDLE_VAR_TOKEN, &file_data) { + let bundle_type = match package_type { + crate::PackageType::Deb => b"__TAURI_BUNDLE_TYPE_VAR_DEB", + crate::PackageType::Rpm => b"__TAURI_BUNDLE_TYPE_VAR_RPM", + crate::PackageType::AppImage => b"__TAURI_BUNDLE_TYPE_VAR_APP", + crate::PackageType::Nsis => b"__TAURI_BUNDLE_TYPE_VAR_NSS", + crate::PackageType::WindowsMsi => b"__TAURI_BUNDLE_TYPE_VAR_MSI", + _ => { + return Err(crate::Error::InvalidPackageType( + package_type.short_name().to_owned(), + )) + } + }; + + file_data[bundle_var_index..bundle_var_index + BUNDLE_VAR_TOKEN.len()] + .copy_from_slice(bundle_type); + std::fs::write(binary, &file_data) + .map_err(|e| crate::Error::BinaryWriteError(e.to_string()))?; + } else { + return Err(crate::Error::MissingBundleTypeVar)?; + } Ok(()) } diff --git a/crates/tauri-bundler/src/bundle/kmp/mod.rs b/crates/tauri-bundler/src/bundle/kmp/mod.rs new file mode 100644 index 000000000000..bc71148a3cb6 --- /dev/null +++ b/crates/tauri-bundler/src/bundle/kmp/mod.rs @@ -0,0 +1,54 @@ +// Knuth–Morris–Pratt algorithm +// based on https://github.com/howeih/rust_kmp +pub fn index_of(pattern: &[u8], target: &[u8]) -> Option { + let failure_function = find_failure_function(pattern); + + let mut t_i: usize = 0; + let mut p_i: usize = 0; + let target_len = target.len(); + let mut result_idx = None; + let pattern_len = pattern.len(); + + while (t_i < target_len) && (p_i < pattern_len) { + if target[t_i] == pattern[p_i] { + if result_idx.is_none() { + result_idx.replace(t_i); + } + t_i += 1; + p_i += 1; + if p_i >= pattern_len { + return result_idx; + } + } else { + if p_i == 0 { + p_i = 0; + t_i += 1; + } else { + p_i = failure_function[p_i - 1]; + } + result_idx = None; + } + } + None +} + +fn find_failure_function(pattern: &[u8]) -> Vec { + let mut i = 1; + let mut j = 0; + let pattern_length = pattern.len(); + let end_i = pattern_length - 1; + let mut failure_function = vec![0usize; pattern_length]; + while i <= end_i { + if pattern[i] == pattern[j] { + failure_function[i] = j + 1; + i += 1; + j += 1; + } else if j == 0 { + failure_function[i] = 0; + i += 1; + } else { + j = failure_function[j - 1]; + } + } + failure_function +} diff --git a/crates/tauri-bundler/src/bundle/linux/mod.rs b/crates/tauri-bundler/src/bundle/linux/mod.rs index ba66a8d397bb..8459b0528efb 100644 --- a/crates/tauri-bundler/src/bundle/linux/mod.rs +++ b/crates/tauri-bundler/src/bundle/linux/mod.rs @@ -7,8 +7,3 @@ pub mod appimage; pub mod debian; pub mod freedesktop; pub mod rpm; - -mod util; - -#[cfg(target_os = "linux")] -pub use util::patch_binary; diff --git a/crates/tauri-bundler/src/bundle/linux/util.rs b/crates/tauri-bundler/src/bundle/linux/util.rs deleted file mode 100644 index be125629581a..000000000000 --- a/crates/tauri-bundler/src/bundle/linux/util.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019-2024 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -/// Change value of __TAURI_BUNDLE_TYPE static variable to mark which package type it was bundled in -#[cfg(target_os = "linux")] -pub fn patch_binary( - binary_path: &std::path::PathBuf, - package_type: &crate::PackageType, -) -> crate::Result<()> { - let mut file_data = std::fs::read(binary_path).expect("Could not read binary file."); - - let elf = match goblin::Object::parse(&file_data)? { - goblin::Object::Elf(elf) => elf, - _ => return Err(crate::Error::GenericError("Not an ELF file".to_owned())), - }; - - let offset = find_bundle_type_symbol(elf).ok_or(crate::Error::MissingBundleTypeVar)?; - let offset = offset as usize; - if offset + 3 <= file_data.len() { - let chars = &mut file_data[offset..offset + 3]; - match package_type { - crate::PackageType::Deb => chars.copy_from_slice(b"DEB"), - crate::PackageType::Rpm => chars.copy_from_slice(b"RPM"), - crate::PackageType::AppImage => chars.copy_from_slice(b"APP"), - _ => { - return Err(crate::Error::InvalidPackageType( - package_type.short_name().to_owned(), - "linux".to_owned(), - )) - } - } - - std::fs::write(binary_path, &file_data) - .map_err(|error| crate::Error::BinaryWriteError(error.to_string()))?; - } else { - return Err(crate::Error::BinaryOffsetOutOfRange); - } - - Ok(()) -} - -/// Find address of a symbol in relocations table -#[cfg(target_os = "linux")] -fn find_bundle_type_symbol(elf: goblin::elf::Elf<'_>) -> Option { - for sym in elf.syms.iter() { - if let Some(name) = elf.strtab.get_at(sym.st_name) { - if name == "__TAURI_BUNDLE_TYPE" { - for reloc in elf.dynrelas.iter() { - if reloc.r_offset == sym.st_value { - return Some(reloc.r_addend.unwrap()); - } - } - } - } - } - - None -} diff --git a/crates/tauri-bundler/src/bundle/windows/mod.rs b/crates/tauri-bundler/src/bundle/windows/mod.rs index 366e000e1cca..b92fb5f56216 100644 --- a/crates/tauri-bundler/src/bundle/windows/mod.rs +++ b/crates/tauri-bundler/src/bundle/windows/mod.rs @@ -14,5 +14,3 @@ pub use util::{ NSIS_OUTPUT_FOLDER_NAME, NSIS_UPDATER_OUTPUT_FOLDER_NAME, WIX_OUTPUT_FOLDER_NAME, WIX_UPDATER_OUTPUT_FOLDER_NAME, }; - -pub use util::patch_binary; diff --git a/crates/tauri-bundler/src/bundle/windows/util.rs b/crates/tauri-bundler/src/bundle/windows/util.rs index 3685d0c06f9d..55cfea3a968f 100644 --- a/crates/tauri-bundler/src/bundle/windows/util.rs +++ b/crates/tauri-bundler/src/bundle/windows/util.rs @@ -77,75 +77,3 @@ pub fn os_bitness<'a>() -> Option<&'a str> { _ => None, } } - -pub fn patch_binary(binary_path: &PathBuf, package_type: &crate::PackageType) -> crate::Result<()> { - let mut file_data = std::fs::read(binary_path)?; - - let pe = match goblin::Object::parse(&file_data)? { - goblin::Object::PE(pe) => pe, - _ => { - return Err(crate::Error::BinaryParseError( - std::io::Error::new(std::io::ErrorKind::InvalidInput, "binary is not a PE file").into(), - )); - } - }; - - let tauri_bundle_section = pe - .sections - .iter() - .find(|s| s.name().unwrap_or_default() == ".taubndl") - .ok_or(crate::Error::MissingBundleTypeVar)?; - - let data_offset = tauri_bundle_section.pointer_to_raw_data as usize; - let pointer_size = if pe.is_64 { 8 } else { 4 }; - let ptr_bytes = file_data - .get(data_offset..data_offset + pointer_size) - .ok_or(crate::Error::BinaryOffsetOutOfRange)?; - // `try_into` is safe to `unwrap` here because we have already checked the slice's size through `get` - let ptr_value = if pe.is_64 { - u64::from_le_bytes(ptr_bytes.try_into().unwrap()) - } else { - u32::from_le_bytes(ptr_bytes.try_into().unwrap()).into() - }; - - let rdata_section = pe - .sections - .iter() - .find(|s| s.name().unwrap_or_default() == ".rdata") - .ok_or_else(|| { - crate::Error::BinaryParseError( - std::io::Error::new(std::io::ErrorKind::InvalidInput, ".rdata section not found").into(), - ) - })?; - - let rva = ptr_value.checked_sub(pe.image_base as u64).ok_or_else(|| { - crate::Error::BinaryParseError( - std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid RVA offset").into(), - ) - })?; - - // see "Relative virtual address (RVA)" for explanation of offset arithmetic here: - // https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#general-concepts - let file_offset = rdata_section.pointer_to_raw_data as usize - + (rva as usize).saturating_sub(rdata_section.virtual_address as usize); - - // Overwrite the string at that offset - let string_bytes = file_data - .get_mut(file_offset..file_offset + 3) - .ok_or(crate::Error::BinaryOffsetOutOfRange)?; - match package_type { - crate::PackageType::Nsis => string_bytes.copy_from_slice(b"NSS"), - crate::PackageType::WindowsMsi => string_bytes.copy_from_slice(b"MSI"), - _ => { - return Err(crate::Error::InvalidPackageType( - package_type.short_name().to_owned(), - "windows".to_owned(), - )); - } - } - - std::fs::write(binary_path, &file_data) - .map_err(|e| crate::Error::BinaryWriteError(e.to_string()))?; - - Ok(()) -} diff --git a/crates/tauri-bundler/src/error.rs b/crates/tauri-bundler/src/error.rs index 518cb6ca9b71..fc60d9235ad0 100644 --- a/crates/tauri-bundler/src/error.rs +++ b/crates/tauri-bundler/src/error.rs @@ -96,24 +96,14 @@ pub enum Error { #[error("Binary parse error: `{0}`")] BinaryParseError(#[from] goblin::error::Error), /// Package type is not supported by target platform - #[error("Wrong package type {0} for platform {1}")] - InvalidPackageType(String, String), + #[error("Wrong package type {0}")] + InvalidPackageType(String), /// Bundle type symbol missing in binary - #[cfg_attr( - target_os = "linux", - error("__TAURI_BUNDLE_TYPE variable not found in binary. Make sure tauri crate and tauri-cli are up to date and that symbol stripping is disabled (https://doc.rust-lang.org/cargo/reference/profiles.html#strip)") - )] - #[cfg_attr( - not(target_os = "linux"), - error("__TAURI_BUNDLE_TYPE variable not found in binary. Make sure tauri crate and tauri-cli are up to date") - )] + #[error("__TAURI_BUNDLE_TYPE variable not found in binary. Make sure tauri crate and tauri-cli are up to date")] MissingBundleTypeVar, /// Failed to write binary file changed #[error("Failed to write binary file changes: `{0}`")] BinaryWriteError(String), - /// Invalid offset while patching binary file - #[error("Invalid offset while patching binary file")] - BinaryOffsetOutOfRange, /// Unsupported architecture. #[error("Architecture Error: `{0}`")] ArchError(String), diff --git a/crates/tauri-utils/src/platform.rs b/crates/tauri-utils/src/platform.rs index 542cea53c839..1b3f5a8f2957 100644 --- a/crates/tauri-utils/src/platform.rs +++ b/crates/tauri-utils/src/platform.rs @@ -353,18 +353,18 @@ fn resource_dir_from>( #[cfg_attr(target_vendor = "apple", link_section = "__DATA,taubndl")] // Marked as `mut` because it could get optimized away without it, // see https://github.com/tauri-apps/tauri/pull/13812 -static mut __TAURI_BUNDLE_TYPE: &str = "UNK"; +static mut __TAURI_BUNDLE_TYPE: &str = "__TAURI_BUNDLE_TYPE_VAR_UNK"; /// Get the type of the bundle current binary is packaged in. /// If the bundle type is unknown, it returns [`Option::None`]. pub fn bundle_type() -> Option { unsafe { match __TAURI_BUNDLE_TYPE { - "DEB" => Some(BundleType::Deb), - "RPM" => Some(BundleType::Rpm), - "APP" => Some(BundleType::AppImage), - "MSI" => Some(BundleType::Msi), - "NSS" => Some(BundleType::Nsis), + "__TAURI_BUNDLE_TYPE_VAR_DEB" => Some(BundleType::Deb), + "__TAURI_BUNDLE_TYPE_VAR_RPM" => Some(BundleType::Rpm), + "__TAURI_BUNDLE_TYPE_VAR_APP" => Some(BundleType::AppImage), + "__TAURI_BUNDLE_TYPE_VAR_MSI" => Some(BundleType::Msi), + "__TAURI_BUNDLE_TYPE_VAR_NSS" => Some(BundleType::Nsis), _ => { if cfg!(target_os = "macos") { Some(BundleType::App) From dad191cfbb9f877a50c28c6115d8632c415ec827 Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Sun, 23 Nov 2025 00:27:53 +0100 Subject: [PATCH 02/11] change file --- .changes/fix-binary-patching.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changes/fix-binary-patching.md diff --git a/.changes/fix-binary-patching.md b/.changes/fix-binary-patching.md new file mode 100644 index 000000000000..27d7bccf560f --- /dev/null +++ b/.changes/fix-binary-patching.md @@ -0,0 +1,8 @@ +--- +"tauri": patch:perf +"tauri-cli": patch:perf +"tauri-bundler": patch:perf +"@tauri-apps/cli": patch:perf +--- + +Change the way bundle type information is added to binary files. Intead of looking up value of a variable we simply look for default value. From ec35668721090d9687ffd63017161901162ebfb4 Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Sun, 23 Nov 2025 09:03:44 +0100 Subject: [PATCH 03/11] clippy --- crates/tauri-bundler/src/bundle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index 79fc3ead18c7..0b889c66b3bf 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -41,7 +41,7 @@ fn patch_binary(binary: &PathBuf, package_type: &PackageType) -> crate::Result<( std::fs::write(binary, &file_data) .map_err(|e| crate::Error::BinaryWriteError(e.to_string()))?; } else { - return Err(crate::Error::MissingBundleTypeVar)?; + return Err(crate::Error::MissingBundleTypeVar); } Ok(()) } From 66b64b15ba592e14de0cfdd8a6fe3015e69118cc Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Sun, 23 Nov 2025 10:01:54 +0100 Subject: [PATCH 04/11] license header --- crates/tauri-bundler/src/bundle/kmp/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/tauri-bundler/src/bundle/kmp/mod.rs b/crates/tauri-bundler/src/bundle/kmp/mod.rs index bc71148a3cb6..863e4145c371 100644 --- a/crates/tauri-bundler/src/bundle/kmp/mod.rs +++ b/crates/tauri-bundler/src/bundle/kmp/mod.rs @@ -1,3 +1,8 @@ +// Copyright 2016-2019 Cargo-Bundle developers +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + // Knuth–Morris–Pratt algorithm // based on https://github.com/howeih/rust_kmp pub fn index_of(pattern: &[u8], target: &[u8]) -> Option { From 88d806498863c5113d57a00c849e4175369bd987 Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Mon, 24 Nov 2025 23:55:04 +0100 Subject: [PATCH 05/11] copy and restore binary --- crates/tauri-bundler/src/bundle.rs | 33 ++++++++++++------------------ 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index 0b889c66b3bf..b8ff7916100e 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -97,22 +97,16 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { .expect("Main binary missing in settings"); let main_binary_path = settings.binary_path(main_binary); - // When packaging multiple binary types, we make a copy of the unsigned main_binary so that we can - // restore it after each package_type step. This avoids two issues: + // We make a copy of the unsigned main_binary so that we can restore it after each package_type step. + // This allows us to patch the binary correctly and avoids two issues: // - modifying a signed binary without updating its PE checksum can break signature verification // - codesigning tools should handle calculating+updating this, we just need to ensure // (re)signing is performed after every `patch_binary()` operation // - signing an already-signed binary can result in multiple signatures, causing verification errors - let main_binary_reset_required = matches!(target_os, TargetPlatform::Windows) - && settings.windows().can_sign() - && package_types.len() > 1; - let mut unsigned_main_binary_copy = tempfile::tempfile()?; - if main_binary_reset_required { - let mut unsigned_main_binary = std::fs::File::open(&main_binary_path)?; - std::io::copy(&mut unsigned_main_binary, &mut unsigned_main_binary_copy)?; - } + let mut main_binary_copy = tempfile::tempfile()?; + let mut main_binary_orignal = std::fs::File::open(&main_binary_path)?; + std::io::copy(&mut main_binary_orignal, &mut main_binary_copy)?; - let mut main_binary_signed = false; let mut bundles = Vec::::new(); for package_type in &package_types { // bundle was already built! e.g. DMG already built .app @@ -126,16 +120,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { // sign main binary for every package type after patch if matches!(target_os, TargetPlatform::Windows) && settings.windows().can_sign() { - if main_binary_signed && main_binary_reset_required { - let mut signed_main_binary = std::fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(&main_binary_path)?; - unsigned_main_binary_copy.seek(SeekFrom::Start(0))?; - std::io::copy(&mut unsigned_main_binary_copy, &mut signed_main_binary)?; - } windows::sign::try_sign(&main_binary_path, settings)?; - main_binary_signed = true; } let bundle_paths = match package_type { @@ -177,6 +162,14 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { package_type: package_type.to_owned(), bundle_paths, }); + + // Restore unsigne and unpatched binary + let mut modified_main_binary = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(&main_binary_path)?; + main_binary_copy.seek(SeekFrom::Start(0))?; + std::io::copy(&mut main_binary_copy, &mut modified_main_binary)?; } if let Some(updater) = settings.updater() { From 2d32f715eaa1fcf1cdad5d433bde3d472cd9ea3d Mon Sep 17 00:00:00 2001 From: kandrelczyk Date: Wed, 26 Nov 2025 08:45:33 +0100 Subject: [PATCH 06/11] Update crates/tauri-bundler/src/bundle.rs Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com> --- crates/tauri-bundler/src/bundle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index b8ff7916100e..79432d9c9dba 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -163,7 +163,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { bundle_paths, }); - // Restore unsigne and unpatched binary + // Restore unsigned and unpatched binary let mut modified_main_binary = std::fs::OpenOptions::new() .write(true) .truncate(true) From 662a1ba153bf208bc913b358fe8a25e5d33efe93 Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Wed, 26 Nov 2025 18:38:56 +0100 Subject: [PATCH 07/11] deprecate error --- crates/tauri-bundler/src/bundle.rs | 3 ++- crates/tauri-bundler/src/error.rs | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index b8ff7916100e..b602c8ad48cf 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -29,7 +29,7 @@ fn patch_binary(binary: &PathBuf, package_type: &PackageType) -> crate::Result<( crate::PackageType::Nsis => b"__TAURI_BUNDLE_TYPE_VAR_NSS", crate::PackageType::WindowsMsi => b"__TAURI_BUNDLE_TYPE_VAR_MSI", _ => { - return Err(crate::Error::InvalidPackageType( + return Err(crate::Error::WrongPackageType( package_type.short_name().to_owned(), )) } @@ -103,6 +103,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { // - codesigning tools should handle calculating+updating this, we just need to ensure // (re)signing is performed after every `patch_binary()` operation // - signing an already-signed binary can result in multiple signatures, causing verification errors + // TODO: change this to work on a copy while preserving the main binary unchanged let mut main_binary_copy = tempfile::tempfile()?; let mut main_binary_orignal = std::fs::File::open(&main_binary_path)?; std::io::copy(&mut main_binary_orignal, &mut main_binary_copy)?; diff --git a/crates/tauri-bundler/src/error.rs b/crates/tauri-bundler/src/error.rs index fc60d9235ad0..1a5a0b3ca8ee 100644 --- a/crates/tauri-bundler/src/error.rs +++ b/crates/tauri-bundler/src/error.rs @@ -96,8 +96,12 @@ pub enum Error { #[error("Binary parse error: `{0}`")] BinaryParseError(#[from] goblin::error::Error), /// Package type is not supported by target platform + #[deprecated(note = "User WrongPackageType instead")] + #[error("Wrong package type {0} for platform {1}")] + InvalidPackageType(String, String), + /// Package type is not supported by target platform #[error("Wrong package type {0}")] - InvalidPackageType(String), + WrongPackageType(String), /// Bundle type symbol missing in binary #[error("__TAURI_BUNDLE_TYPE variable not found in binary. Make sure tauri crate and tauri-cli are up to date")] MissingBundleTypeVar, From 3799c5ba8816545d144e69e77ad6945178c2cd36 Mon Sep 17 00:00:00 2001 From: kandrelczyk Date: Thu, 27 Nov 2025 22:37:07 +0100 Subject: [PATCH 08/11] Update .changes/fix-binary-patching.md Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com> --- .changes/fix-binary-patching.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.changes/fix-binary-patching.md b/.changes/fix-binary-patching.md index 27d7bccf560f..0d23f230056c 100644 --- a/.changes/fix-binary-patching.md +++ b/.changes/fix-binary-patching.md @@ -1,8 +1,8 @@ --- -"tauri": patch:perf -"tauri-cli": patch:perf -"tauri-bundler": patch:perf -"@tauri-apps/cli": patch:perf +"tauri": patch:changes +"tauri-cli": patch:changes +"tauri-bundler": patch:changes +"@tauri-apps/cli": patch:changes --- Change the way bundle type information is added to binary files. Intead of looking up value of a variable we simply look for default value. From ff5ab53a9400874ad80bfdb42a0421a6e20cc760 Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Thu, 27 Nov 2025 22:46:20 +0100 Subject: [PATCH 09/11] deprecate error and revernt package type validation --- crates/tauri-bundler/src/bundle.rs | 13 ++++++++++++- crates/tauri-bundler/src/error.rs | 8 ++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index 563ba190c07e..ae9148d3b368 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -22,15 +22,26 @@ fn patch_binary(binary: &PathBuf, package_type: &PackageType) -> crate::Result<( let mut file_data = std::fs::read(binary).expect("Could not read binary file."); if let Some(bundle_var_index) = kmp::index_of(BUNDLE_VAR_TOKEN, &file_data) { + #[cfg(target_os = "linux")] let bundle_type = match package_type { crate::PackageType::Deb => b"__TAURI_BUNDLE_TYPE_VAR_DEB", crate::PackageType::Rpm => b"__TAURI_BUNDLE_TYPE_VAR_RPM", crate::PackageType::AppImage => b"__TAURI_BUNDLE_TYPE_VAR_APP", + _ => { + return Err(crate::Error::InvalidPackageType( + package_type.short_name().to_owned(), + "Linux".to_owned(), + )) + } + }; + #[cfg(target_os = "windows")] + let bundle_type = match package_type { crate::PackageType::Nsis => b"__TAURI_BUNDLE_TYPE_VAR_NSS", crate::PackageType::WindowsMsi => b"__TAURI_BUNDLE_TYPE_VAR_MSI", _ => { - return Err(crate::Error::WrongPackageType( + return Err(crate::Error::InvalidPackageType( package_type.short_name().to_owned(), + "Windows".to_owned(), )) } }; diff --git a/crates/tauri-bundler/src/error.rs b/crates/tauri-bundler/src/error.rs index 1a5a0b3ca8ee..40547a3eea39 100644 --- a/crates/tauri-bundler/src/error.rs +++ b/crates/tauri-bundler/src/error.rs @@ -96,18 +96,18 @@ pub enum Error { #[error("Binary parse error: `{0}`")] BinaryParseError(#[from] goblin::error::Error), /// Package type is not supported by target platform - #[deprecated(note = "User WrongPackageType instead")] #[error("Wrong package type {0} for platform {1}")] InvalidPackageType(String, String), - /// Package type is not supported by target platform - #[error("Wrong package type {0}")] - WrongPackageType(String), /// Bundle type symbol missing in binary #[error("__TAURI_BUNDLE_TYPE variable not found in binary. Make sure tauri crate and tauri-cli are up to date")] MissingBundleTypeVar, /// Failed to write binary file changed #[error("Failed to write binary file changes: `{0}`")] BinaryWriteError(String), + /// Invalid offset while patching binary file + #[deprecated] + #[error("Invalid offset while patching binary file")] + BinaryOffsetOutOfRange, /// Unsupported architecture. #[error("Architecture Error: `{0}`")] ArchError(String), From 403586913aea70323b702b2d5d78f1d28fa00733 Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Thu, 27 Nov 2025 23:59:33 +0100 Subject: [PATCH 10/11] fix mac --- crates/tauri-bundler/src/bundle.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index ae9148d3b368..b7a6ed084df5 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -18,6 +18,7 @@ use tauri_utils::{display_path, platform::Target as TargetPlatform}; const BUNDLE_VAR_TOKEN: &[u8] = b"__TAURI_BUNDLE_TYPE_VAR_UNK"; /// Patch a binary with bundle type information +#[cfg(any(target_os = "linux", target_os = "windows"))] fn patch_binary(binary: &PathBuf, package_type: &PackageType) -> crate::Result<()> { let mut file_data = std::fs::read(binary).expect("Could not read binary file."); @@ -126,6 +127,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { continue; } + #[cfg(any(target_os = "linux", target_os = "windows"))] if let Err(e) = patch_binary(&main_binary_path, package_type) { log::warn!("Failed to add bundler type to the binary: {e}. Updater plugin may not be able to update this package. This shouldn't normally happen, please report it to https://github.com/tauri-apps/tauri/issues"); } From ad7335b651b6898e536d609db4e5bb14758f3acc Mon Sep 17 00:00:00 2001 From: Krzysztof Andrelczyk Date: Fri, 28 Nov 2025 20:01:05 +0100 Subject: [PATCH 11/11] fix warning --- crates/tauri-bundler/src/bundle.rs | 2 ++ crates/tauri-bundler/src/bundle/kmp/mod.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index b7a6ed084df5..f4916085fa27 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -4,6 +4,7 @@ // SPDX-License-Identifier: MIT mod category; +#[cfg(any(target_os = "linux", target_os = "windows"))] mod kmp; #[cfg(target_os = "linux")] mod linux; @@ -16,6 +17,7 @@ mod windows; use tauri_utils::{display_path, platform::Target as TargetPlatform}; +#[cfg(any(target_os = "linux", target_os = "windows"))] const BUNDLE_VAR_TOKEN: &[u8] = b"__TAURI_BUNDLE_TYPE_VAR_UNK"; /// Patch a binary with bundle type information #[cfg(any(target_os = "linux", target_os = "windows"))] diff --git a/crates/tauri-bundler/src/bundle/kmp/mod.rs b/crates/tauri-bundler/src/bundle/kmp/mod.rs index 863e4145c371..3e8489023044 100644 --- a/crates/tauri-bundler/src/bundle/kmp/mod.rs +++ b/crates/tauri-bundler/src/bundle/kmp/mod.rs @@ -5,6 +5,7 @@ // Knuth–Morris–Pratt algorithm // based on https://github.com/howeih/rust_kmp +#[cfg(any(target_os = "linux", target_os = "windows"))] pub fn index_of(pattern: &[u8], target: &[u8]) -> Option { let failure_function = find_failure_function(pattern); @@ -37,6 +38,7 @@ pub fn index_of(pattern: &[u8], target: &[u8]) -> Option { None } +#[cfg(any(target_os = "linux", target_os = "windows"))] fn find_failure_function(pattern: &[u8]) -> Vec { let mut i = 1; let mut j = 0;