From 3582e27e6325f05b9963cdcdf9746e65e8c3be23 Mon Sep 17 00:00:00 2001 From: l Date: Mon, 11 Nov 2024 06:48:19 +0000 Subject: [PATCH] fix: do not crash in ServerConfig::from_url() on unknown method (#1762) --- crates/shadowsocks/src/config.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/crates/shadowsocks/src/config.rs b/crates/shadowsocks/src/config.rs index c16396e755d7..8e475145eb17 100644 --- a/crates/shadowsocks/src/config.rs +++ b/crates/shadowsocks/src/config.rs @@ -905,7 +905,13 @@ impl ServerConfig { } }; - let method = method.parse().expect("method"); + let method = match method.parse::() { + Ok(m) => m, + Err(err) => { + error!("failed to parse \"{}\" to CipherKind, err: {:?}", method, err); + return Err(UrlParseError::InvalidMethod); + } + }; let mut svrconfig = ServerConfig::new(addr, pwd, method); if let Some(q) = parsed.query() { @@ -959,6 +965,7 @@ impl ServerConfig { pub enum UrlParseError { ParseError(url::ParseError), InvalidScheme, + InvalidMethod, InvalidUserInfo, MissingHost, InvalidAuthInfo, @@ -977,6 +984,7 @@ impl fmt::Display for UrlParseError { match *self { UrlParseError::ParseError(ref err) => fmt::Display::fmt(err, f), UrlParseError::InvalidScheme => write!(f, "URL must have \"ss://\" scheme"), + UrlParseError::InvalidMethod => write!(f, "unknown encryption method"), UrlParseError::InvalidUserInfo => write!(f, "invalid user info"), UrlParseError::MissingHost => write!(f, "missing host"), UrlParseError::InvalidAuthInfo => write!(f, "invalid authentication info"), @@ -991,6 +999,7 @@ impl error::Error for UrlParseError { match *self { UrlParseError::ParseError(ref err) => Some(err as &dyn error::Error), UrlParseError::InvalidScheme => None, + UrlParseError::InvalidMethod => None, UrlParseError::InvalidUserInfo => None, UrlParseError::MissingHost => None, UrlParseError::InvalidAuthInfo => None, @@ -1405,3 +1414,14 @@ impl FromStr for ReplayAttackPolicy { } } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_server_config_from_url() { + let server_config = ServerConfig::from_url("ss://foo:bar@127.0.0.1:9999"); + assert!(matches!(server_config, Err(UrlParseError::InvalidMethod))); + } +}