JID stringprep errors return a JidParseError instead of panic (#84)

This commit is contained in:
xmppftw 2023-06-07 13:16:34 +02:00
parent c8dcf5e7a7
commit befdafb40d
2 changed files with 24 additions and 8 deletions

View file

@ -4,6 +4,8 @@ Unreleased
- serde: Jid is now using untagged enum representation (#66) - serde: Jid is now using untagged enum representation (#66)
* Additions * Additions
- From<&Jid> is now implemented for String (#69) - 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: Version 0.9.3, release 2022-03-07:
* Updates * Updates

View file

@ -42,10 +42,18 @@ pub enum JidParseError {
EmptyResource, EmptyResource,
#[cfg(feature = "icu")] #[cfg(feature = "icu")]
/// TODO /// Happens when the JID is invalid according to stringprep. TODO: make errors
/// meaningful.
IcuError(icu::Error), IcuError(icu::Error),
} }
#[cfg(feature = "icu")]
impl From<icu::Error> for JidParseError {
fn from(e: icu::Error) -> JidParseError {
JidParseError::IcuError(e)
}
}
impl StdError for JidParseError {} impl StdError for JidParseError {}
impl fmt::Display for JidParseError { impl fmt::Display for JidParseError {
@ -410,13 +418,19 @@ fn _from_str(s: &str) -> Result<StringJid, JidParseError> {
let domain = domain.ok_or(JidParseError::NoDomain)?; let domain = domain.ok_or(JidParseError::NoDomain)?;
#[cfg(feature = "icu")] #[cfg(feature = "icu")]
let (node, domain, resource) = { let (node, domain, resource) = {
let icu = Icu::new().unwrap(); let icu = Icu::new()?;
let node = node.map(|node| icu.nodeprep(&node, Strict::AllowUnassigned).unwrap()); let node = if let Some(node) = node {
let domain = icu.idna2008.to_unicode(&domain).unwrap(); Some(icu.nodeprep(&node, Strict::AllowUnassigned)?)
let resource = resource.map(|resource| { } else {
icu.resourceprep(&resource, Strict::AllowUnassigned) None
.unwrap() };
}); 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) (node, domain, resource)
}; };
Ok((node, domain, resource)) Ok((node, domain, resource))