1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-22 21:01:36 +03:00

config: validate consistency of domain names

refs: https://github.com/wez/wezterm/issues/2618
This commit is contained in:
Wez Furlong 2022-10-11 06:57:45 -07:00
parent ed63d728bf
commit de466cfa64
9 changed files with 73 additions and 7 deletions

View File

@ -842,6 +842,7 @@ impl Config {
p.display() p.display()
) )
})?; })?;
cfg.check_consistency()?;
// Compute but discard the key bindings here so that we raise any // Compute but discard the key bindings here so that we raise any
// problems earlier than we use them. // problems earlier than we use them.
@ -914,6 +915,44 @@ impl Config {
Ok(config) Ok(config)
} }
/// Check for logical conflicts in the config
pub fn check_consistency(&self) -> anyhow::Result<()> {
self.check_domain_consistency()?;
Ok(())
}
fn check_domain_consistency(&self) -> anyhow::Result<()> {
let mut domains = HashMap::new();
let mut check_domain = |name: &str, kind: &str| {
if let Some(exists) = domains.get(name) {
anyhow::bail!(
"{kind} with name \"{name}\" conflicts with \
another existing {exists} with the same name"
);
}
domains.insert(name.to_string(), kind.to_string());
Ok(())
};
for d in &self.unix_domains {
check_domain(&d.name, "unix domain")?;
}
for d in &self.ssh_domains {
check_domain(&d.name, "ssh domain")?;
}
for d in &self.exec_domains {
check_domain(&d.name, "exec domain")?;
}
for d in &self.wsl_domains {
check_domain(&d.name, "wsl domain")?;
}
for d in &self.tls_clients {
check_domain(&d.name, "tls domain")?;
}
Ok(())
}
pub fn default_config() -> Self { pub fn default_config() -> Self {
Self::default().compute_extra_defaults(None) Self::default().compute_extra_defaults(None)
} }
@ -1656,16 +1695,16 @@ impl Default for ImePreeditRendering {
} }
} }
fn validate_row_or_col(value: u16) -> Result<(), String> { fn validate_row_or_col(value: &u16) -> Result<(), String> {
if value < 1 { if *value < 1 {
Err("initial_cols and initial_rows must be non-zero".to_string()) Err("initial_cols and initial_rows must be non-zero".to_string())
} else { } else {
Ok(()) Ok(())
} }
} }
fn validate_line_height(value: f64) -> Result<(), String> { fn validate_line_height(value: &f64) -> Result<(), String> {
if value <= 0.0 { if *value <= 0.0 {
Err(format!( Err(format!(
"Illegal value {value} for line_height; it must be positive and greater than zero!" "Illegal value {value} for line_height; it must be positive and greater than zero!"
)) ))
@ -1673,3 +1712,15 @@ fn validate_line_height(value: f64) -> Result<(), String> {
Ok(()) Ok(())
} }
} }
pub(crate) fn validate_domain_name(name: &str) -> Result<(), String> {
if name == "local" {
Err(format!(
"\"{name}\" is a built-in domain and cannot be redefined"
))
} else if name == "" {
Err("the empty string is an invalid domain name".to_string())
} else {
Ok(())
}
}

View File

@ -1,3 +1,4 @@
use crate::config::validate_domain_name;
use luahelper::impl_lua_conversion_dynamic; use luahelper::impl_lua_conversion_dynamic;
use wezterm_dynamic::{FromDynamic, ToDynamic, Value}; use wezterm_dynamic::{FromDynamic, ToDynamic, Value};
@ -10,6 +11,7 @@ impl_lua_conversion_dynamic!(ValueOrFunc);
#[derive(Debug, Clone, FromDynamic, ToDynamic)] #[derive(Debug, Clone, FromDynamic, ToDynamic)]
pub struct ExecDomain { pub struct ExecDomain {
#[dynamic(validate = "validate_domain_name")]
pub name: String, pub name: String,
pub fixup_command: String, pub fixup_command: String,
pub label: Option<ValueOrFunc>, pub label: Option<ValueOrFunc>,

View File

@ -284,6 +284,8 @@ fn default_config_with_overrides_applied() -> anyhow::Result<Config> {
// problems earlier than we use them. // problems earlier than we use them.
let _ = cfg.key_bindings(); let _ = cfg.key_bindings();
cfg.check_consistency()?;
Ok(cfg) Ok(cfg)
} }

View File

@ -1,3 +1,4 @@
use crate::config::validate_domain_name;
use crate::*; use crate::*;
use std::fmt::Display; use std::fmt::Display;
use std::str::FromStr; use std::str::FromStr;
@ -49,6 +50,7 @@ impl Default for Shell {
pub struct SshDomain { pub struct SshDomain {
/// The name of this specific domain. Must be unique amongst /// The name of this specific domain. Must be unique amongst
/// all types of domain in the configuration file. /// all types of domain in the configuration file.
#[dynamic(validate = "validate_domain_name")]
pub name: String, pub name: String,
/// identifies the host:port pair of the remote server. /// identifies the host:port pair of the remote server.

View File

@ -1,3 +1,4 @@
use crate::config::validate_domain_name;
use crate::*; use crate::*;
use wezterm_dynamic::{FromDynamic, ToDynamic}; use wezterm_dynamic::{FromDynamic, ToDynamic};
@ -29,6 +30,7 @@ pub struct TlsDomainServer {
pub struct TlsDomainClient { pub struct TlsDomainClient {
/// The name of this specific domain. Must be unique amongst /// The name of this specific domain. Must be unique amongst
/// all types of domain in the configuration file. /// all types of domain in the configuration file.
#[dynamic(validate = "validate_domain_name")]
pub name: String, pub name: String,
/// If set, use ssh to connect, start the server, and obtain /// If set, use ssh to connect, start the server, and obtain

View File

@ -1,3 +1,4 @@
use crate::config::validate_domain_name;
use crate::*; use crate::*;
use std::path::PathBuf; use std::path::PathBuf;
use wezterm_dynamic::{FromDynamic, ToDynamic}; use wezterm_dynamic::{FromDynamic, ToDynamic};
@ -8,6 +9,7 @@ use wezterm_dynamic::{FromDynamic, ToDynamic};
pub struct UnixDomain { pub struct UnixDomain {
/// The name of this specific domain. Must be unique amongst /// The name of this specific domain. Must be unique amongst
/// all types of domain in the configuration file. /// all types of domain in the configuration file.
#[dynamic(validate = "validate_domain_name")]
pub name: String, pub name: String,
/// The path to the socket. If unspecified, a resonable default /// The path to the socket. If unspecified, a resonable default
@ -104,6 +106,7 @@ impl UnixDomain {
pub fn default_unix_domains() -> Vec<Self> { pub fn default_unix_domains() -> Vec<Self> {
vec![UnixDomain { vec![UnixDomain {
name: "unix".to_string(),
read_timeout: default_read_timeout(), read_timeout: default_read_timeout(),
write_timeout: default_read_timeout(), write_timeout: default_read_timeout(),
..Default::default() ..Default::default()

View File

@ -1,3 +1,4 @@
use crate::config::validate_domain_name;
use crate::*; use crate::*;
use luahelper::impl_lua_conversion_dynamic; use luahelper::impl_lua_conversion_dynamic;
use std::collections::HashMap; use std::collections::HashMap;
@ -5,6 +6,7 @@ use wezterm_dynamic::{FromDynamic, ToDynamic};
#[derive(Default, Debug, Clone, FromDynamic, ToDynamic)] #[derive(Default, Debug, Clone, FromDynamic, ToDynamic)]
pub struct WslDomain { pub struct WslDomain {
#[dynamic(validate = "validate_domain_name")]
pub name: String, pub name: String,
pub distribution: Option<String>, pub distribution: Option<String>,
pub username: Option<String>, pub username: Option<String>,

View File

@ -73,9 +73,11 @@ As features stabilize some brief notes about them will accumulate here.
* CharSelect panic when pressing enter when no matches were found * CharSelect panic when pressing enter when no matches were found
[#2580](https://github.com/wez/wezterm/issues/2580) [#2580](https://github.com/wez/wezterm/issues/2580)
* Panic when setting `initial_rows` or `initial_cols` to `0` * Panic when setting `initial_rows` or `initial_cols` to `0`
[2593](https://github.com/wez/wezterm/issues/2593) [#2593](https://github.com/wez/wezterm/issues/2593)
* X11: Crash on systems using DRI2 based Intel graphics * X11: Crash on systems using DRI2 based Intel graphics
[2559](https://github.com/wez/wezterm/issues/2559) [#2559](https://github.com/wez/wezterm/issues/2559)
* Missing validation of conflicting domain names
[#2618](https://github.com/wez/wezterm/issues/2618)
#### Changed #### Changed
* Removed Last Resort fallback font * Removed Last Resort fallback font

View File

@ -112,7 +112,7 @@ impl<'a> FieldInfo<'a> {
}; };
let validate_value = if let Some(validator) = &self.validate { let validate_value = if let Some(validator) = &self.validate {
quote!( quote!(
#validator(value).map_err(|msg| { #validator(&value).map_err(|msg| {
wezterm_dynamic::Error::ErrorInField{ wezterm_dynamic::Error::ErrorInField{
type_name: #struct_name, type_name: #struct_name,
field_name: #name, field_name: #name,