From 2cafecb0041ff1fb5dedcbaae191699d8aeb5e2b Mon Sep 17 00:00:00 2001 From: xmppftw Date: Wed, 7 Jun 2023 13:16:34 +0200 Subject: [PATCH] JID stringprep errors return a JidParseError instead of panic (#84) --- jid/CHANGELOG.md | 2 ++ jid/src/lib.rs | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/jid/CHANGELOG.md b/jid/CHANGELOG.md index a252435..1adbf28 100644 --- a/jid/CHANGELOG.md +++ b/jid/CHANGELOG.md @@ -4,6 +4,8 @@ Unreleased - serde: Jid is now using untagged enum representation (#66) * Additions - From<&Jid> is now implemented for String (#69) + - Parsing invalid JIDs with stringprep feature no longer results in panic, + returning JidParseError::IcuError instead (#84) Version 0.9.3, release 2022-03-07: * Updates diff --git a/jid/src/lib.rs b/jid/src/lib.rs index fa89863..3fc389d 100644 --- a/jid/src/lib.rs +++ b/jid/src/lib.rs @@ -42,10 +42,18 @@ pub enum JidParseError { EmptyResource, #[cfg(feature = "icu")] - /// TODO + /// Happens when the JID is invalid according to stringprep. TODO: make errors + /// meaningful. IcuError(icu::Error), } +#[cfg(feature = "icu")] +impl From for JidParseError { + fn from(e: icu::Error) -> JidParseError { + JidParseError::IcuError(e) + } +} + impl StdError for JidParseError {} impl fmt::Display for JidParseError { @@ -410,13 +418,19 @@ fn _from_str(s: &str) -> Result { let domain = domain.ok_or(JidParseError::NoDomain)?; #[cfg(feature = "icu")] let (node, domain, resource) = { - let icu = Icu::new().unwrap(); - let node = node.map(|node| icu.nodeprep(&node, Strict::AllowUnassigned).unwrap()); - let domain = icu.idna2008.to_unicode(&domain).unwrap(); - let resource = resource.map(|resource| { - icu.resourceprep(&resource, Strict::AllowUnassigned) - .unwrap() - }); + let icu = Icu::new()?; + let node = if let Some(node) = node { + Some(icu.nodeprep(&node, Strict::AllowUnassigned)?) + } else { + None + }; + let domain = icu.idna2008.to_unicode(&domain)?; + let resource = if let Some(resource) = resource { + Some(icu.resourceprep(&resource, Strict::AllowUnassigned)?) + } else { + None + }; + (node, domain, resource) }; Ok((node, domain, resource))