From 458c0901878c507e4c9ecfcc9b81fa1040cd06a0 Mon Sep 17 00:00:00 2001 From: ming Date: Thu, 27 Aug 2026 22:19:50 +0800 Subject: [PATCH] fix(bindings): reject empty LaunchApp package names --- crates/core/src/bindings.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/core/src/bindings.rs b/crates/core/src/bindings.rs index ecf433d..c5b49e6 100644 --- a/crates/core/src/bindings.rs +++ b/crates/core/src/bindings.rs @@ -68,6 +68,12 @@ pub fn save_binding(mut binding: Binding) -> Result { bail!("Binding label is required"); } + if let BindingAction::LaunchApp { package_name } = &binding.action { + if package_name.trim().is_empty() { + bail!("LaunchApp package name is required"); + } + } + binding.hotkey = binding.hotkey.trim().to_string(); if !binding.hotkey.is_empty() @@ -367,6 +373,26 @@ mod tests { }); } + #[test] + fn rejects_launch_app_without_a_package_name_before_writing() { + with_temp_home(|| { + let invalid = Binding { + id: "launch-empty".to_string(), + label: "Launch app".to_string(), + hotkey: String::new(), + favorite: false, + favorite_order: 0, + action: BindingAction::LaunchApp { + package_name: " ".to_string(), + }, + }; + + let error = save_binding(invalid).expect_err("empty package name must be rejected"); + assert_eq!(error.to_string(), "LaunchApp package name is required"); + assert!(!stored_bindings_path().exists()); + }); + } + #[test] fn replaces_bindings_without_leaving_temporary_files() { with_temp_home(|| {