diff options
author | Aram Drevekenin <aram@poor.dev> | 2022-10-20 20:16:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-20 20:16:46 +0200 |
commit | e62bb93df3a5d8f910491bfed8aea2463d5a0dec (patch) | |
tree | 3cd3da58e3a5d3deab665c0e56797888429fcae7 | |
parent | ebc4222d6af7734e346dcf00442422cadfe5cdf6 (diff) |
fix(layouts): various bugs and better errors (#1831)
* fix(layout): error on percent size 0
* fix(command): better error on invalid commands
* fix(layouts): better error on unknown pane nodes
* fix(layouts): disallow certain template names
* style(fmt): rustfmt
-rw-r--r-- | zellij-server/src/os_input_output.rs | 8 | ||||
-rw-r--r-- | zellij-utils/src/input/layout.rs | 6 | ||||
-rw-r--r-- | zellij-utils/src/kdl/kdl_layout_parser.rs | 38 |
3 files changed, 48 insertions, 4 deletions
diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs index 29b7c75a8..9a8ce0088 100644 --- a/zellij-server/src/os_input_output.rs +++ b/zellij-server/src/os_input_output.rs @@ -104,12 +104,13 @@ fn command_exists(cmd: &RunCommand) -> bool { let command = &cmd.command; match cmd.cwd.as_ref() { Some(cwd) => { - if cwd.join(&command).exists() { + let full_command = cwd.join(&command); + if full_command.exists() && full_command.is_file() { return true; } }, None => { - if command.exists() { + if command.exists() && command.is_file() { return true; } }, @@ -117,7 +118,8 @@ fn command_exists(cmd: &RunCommand) -> bool { if let Some(paths) = env::var_os("PATH") { for path in env::split_paths(&paths) { - if path.join(command).exists() { + let full_command = path.join(command); + if full_command.exists() && full_command.is_file() { return true; } } diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index b041412e2..e283b4455 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -575,7 +575,11 @@ impl FromStr for SplitSize { if s.chars().last() == Some('%') { let char_count = s.chars().count(); let percent_size = usize::from_str_radix(&s[..char_count.saturating_sub(1)], 10)?; - Ok(SplitSize::Percent(percent_size)) + if percent_size > 0 && percent_size <= 100 { + Ok(SplitSize::Percent(percent_size)) + } else { + Err("Percent must be between 0 and 100".into()) + } } else { let fixed_size = usize::from_str_radix(s, 10)?; Ok(SplitSize::Fixed(fixed_size)) diff --git a/zellij-utils/src/kdl/kdl_layout_parser.rs b/zellij-utils/src/kdl/kdl_layout_parser.rs index 28d9e2f1d..bc127f3f1 100644 --- a/zellij-utils/src/kdl/kdl_layout_parser.rs +++ b/zellij-utils/src/kdl/kdl_layout_parser.rs @@ -97,6 +97,38 @@ impl<'a> KdlLayoutParser<'a> { Ok(()) } } + fn assert_legal_template_name( + &self, + name: &str, + kdl_node: &KdlNode, + ) -> Result<(), ConfigError> { + if name.is_empty() { + Err(ConfigError::new_kdl_error( + format!("Template names cannot be empty"), + kdl_node.span().offset(), + kdl_node.span().len(), + )) + } else if name.contains(')') || name.contains('(') { + Err(ConfigError::new_kdl_error( + format!("Template names cannot contain parantheses"), + kdl_node.span().offset(), + kdl_node.span().len(), + )) + } else if name + .chars() + .next() + .map(|first_char| first_char.is_numeric()) + .unwrap_or(false) + { + Err(ConfigError::new_kdl_error( + format!("Template names cannot start with numbers"), + kdl_node.span().offset(), + kdl_node.span().len(), + )) + } else { + Ok(()) + } + } fn parse_split_size(&self, kdl_node: &KdlNode) -> Result<Option<SplitSize>, ConfigError> { if let Some(size) = kdl_get_string_property_or_child_value!(kdl_node, "size") { match SplitSize::from_str(size) { @@ -404,6 +436,7 @@ impl<'a> KdlLayoutParser<'a> { kdl_node.span().len(), ))?; self.assert_legal_node_name(&template_name, kdl_node)?; + self.assert_legal_template_name(&template_name, kdl_node)?; let borderless = kdl_get_bool_property_or_child_value_with_error!(kdl_node, "borderless"); let focus = kdl_get_bool_property_or_child_value_with_error!(kdl_node, "focus"); let split_size = self.parse_split_size(kdl_node)?; @@ -731,6 +764,7 @@ impl<'a> KdlLayoutParser<'a> { kdl_node.span().len(), ))?; self.assert_legal_node_name(&template_name, kdl_node)?; + self.assert_legal_template_name(&template_name, kdl_node)?; if self.tab_templates.contains_key(&template_name) { return Err(ConfigError::new_kdl_error( format!( @@ -854,6 +888,10 @@ impl<'a> KdlLayoutParser<'a> { dependency_tree.insert(template_name, template_children); } } + let all_pane_template_names: HashSet<&str> = dependency_tree.keys().cloned().collect(); + for (_pane_template_name, dependencies) in dependency_tree.iter_mut() { + dependencies.retain(|d| all_pane_template_names.contains(d)); + } Ok(dependency_tree) } fn get_pane_template_dependencies( |