diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-10-10 18:57:30 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-10-11 10:20:31 +0200 |
commit | c1a3ab926e4bd4a73b1becdf08b8f4ecb26fc628 (patch) | |
tree | 3219b2c5f8df7203ab87bfb91633013be218659c | |
parent | 3ec528dd304f65b7d7c0e537920c5b93a4d6b9c0 (diff) |
openpgp: Add non-allocating accessors for parsed User ID components.
- Now that we use OnceCell for the cache, we can hand out references
to the cached data. This closes the gap between UserID and
ConventionallyParsedUserID, hence I think this addresses the
concern in #377.
- Deprecate the allocating variants.
- Fixes #377.
-rw-r--r-- | autocrypt/src/lib.rs | 2 | ||||
-rw-r--r-- | net/src/lib.rs | 4 | ||||
-rw-r--r-- | net/src/wkd.rs | 4 | ||||
-rw-r--r-- | openpgp/NEWS | 8 | ||||
-rw-r--r-- | openpgp/src/packet/userid.rs | 43 |
5 files changed, 52 insertions, 9 deletions
diff --git a/autocrypt/src/lib.rs b/autocrypt/src/lib.rs index b76c4208..074ecc7d 100644 --- a/autocrypt/src/lib.rs +++ b/autocrypt/src/lib.rs @@ -137,7 +137,7 @@ impl AutocryptHeader { let mut found_one = false; for uidb in cert.userids().with_policy(policy, None) { // XXX: Fix match once we have the rfc2822-name-addr. - if let Ok(Some(a)) = uidb.userid().email() { + if let Ok(Some(a)) = uidb.userid().email2() { if a == addr { acc.push(uidb.userid().clone().into()); acc.push(uidb.binding_signature().clone().into()); diff --git a/net/src/lib.rs b/net/src/lib.rs index 60808c8c..750a7bc2 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -191,7 +191,7 @@ impl KeyServer { -> Result<Vec<Cert>> { let userid = userid.into(); - let email = userid.email().and_then(|addr| addr.ok_or_else(|| + let email = userid.email2().and_then(|addr| addr.ok_or_else(|| openpgp::Error::InvalidArgument( "UserID does not contain an email address".into()).into()))?; let url = self.request_url.join( @@ -205,7 +205,7 @@ impl KeyServer { for certo in CertParser::from_bytes(&body)? { let cert = certo?; if cert.userids().any(|uid| { - uid.email().ok() + uid.email2().ok() .and_then(|addro| addro) .map(|addr| addr == email) .unwrap_or(false) diff --git a/net/src/wkd.rs b/net/src/wkd.rs index ca918733..c1bb0852 100644 --- a/net/src/wkd.rs +++ b/net/src/wkd.rs @@ -167,7 +167,7 @@ fn parse_body<S: AsRef<str>>(body: &[u8], email_address: S) // method to maintain .filter(|cert| {cert.userids() .any(|uidb| - if let Ok(Some(a)) = uidb.userid().email() { + if let Ok(Some(a)) = uidb.userid().email2() { a == email_address } else { false }) }).cloned().collect(); @@ -244,7 +244,7 @@ pub async fn get<S: AsRef<str>>(c: &reqwest::Client, email_address: S) fn get_cert_domains<'a>(domain: &'a str, cert: &ValidCert<'a>) -> impl Iterator<Item = Url> + 'a { cert.userids().filter_map(move |uidb| { - uidb.userid().email().unwrap_or(None).and_then(|addr| { + uidb.userid().email2().unwrap_or(None).and_then(|addr| { if EmailAddress::from(&addr).ok().map(|e| e.domain == domain) .unwrap_or(false) { diff --git a/openpgp/NEWS b/openpgp/NEWS index 926380eb..ceb840f0 100644 --- a/openpgp/NEWS +++ b/openpgp/NEWS @@ -44,6 +44,10 @@ - crypto::ecdh::decrypt_unwrap2 - packet::Key::generate_dsa - packet::Key::generate_elgamal + - packet::UserID::comment2 + - packet::UserID::email2 + - packet::UserID::name2 + - packet::UserID::uri2 - parse::PacketParser::start_hashing - parse::PacketParserBuilder::automatic_hashing - impl Eq, PartialEq for regex::Regex @@ -63,6 +67,10 @@ ** Deprecated functionality - cert::Preferences::preferred_aead_algorithms - crypto::ecdh::decrypt_unwrap + - packet::UserID::comment + - packet::UserID::email + - packet::UserID::name + - packet::UserID::uri - packet::signature::SignatureBuilder::set_preferred_aead_algorithms - packet::signature::subpacket::SubpacketAreas::preferred_aead_algorithms - packet::signature::subpacket::SubpacketTag::PreferredAEADAlgorithms diff --git a/openpgp/src/packet/userid.rs b/openpgp/src/packet/userid.rs index 1b76a660..1ad272f0 100644 --- a/openpgp/src/packet/userid.rs +++ b/openpgp/src/packet/userid.rs @@ -872,6 +872,15 @@ impl UserID { /// See [conventional User ID] for more information. /// /// [conventional User ID]: #conventional-user-ids + pub fn name2(&self) -> Result<Option<&str>> { + Ok(self.do_parse()?.name()) + } + + /// Parses the User ID according to de facto conventions, and + /// returns the name component, if any. + /// + /// Like [`UserID::name2`], but heap-allocates. + #[deprecated(note = "Use UserID::name2")] pub fn name(&self) -> Result<Option<String>> { Ok(self.do_parse()?.name().map(|s| s.to_string())) } @@ -882,6 +891,15 @@ impl UserID { /// See [conventional User ID] for more information. /// /// [conventional User ID]: #conventional-user-ids + pub fn comment2(&self) -> Result<Option<&str>> { + Ok(self.do_parse()?.comment()) + } + + /// Parses the User ID according to de facto conventions, and + /// returns the comment field, if any. + /// + /// Like [`UserID::comment2`], but heap-allocates. + #[deprecated(note = "Use UserID::comment2")] pub fn comment(&self) -> Result<Option<String>> { Ok(self.do_parse()?.comment().map(|s| s.to_string())) } @@ -892,6 +910,15 @@ impl UserID { /// See [conventional User ID] for more information. /// /// [conventional User ID]: #conventional-user-ids + pub fn email2(&self) -> Result<Option<&str>> { + Ok(self.do_parse()?.email()) + } + + /// Parses the User ID according to de facto conventions, and + /// returns the email address, if any. + /// + /// Like [`UserID::email2`], but heap-allocates. + #[deprecated(note = "Use UserID::email2")] pub fn email(&self) -> Result<Option<String>> { Ok(self.do_parse()?.email().map(|s| s.to_string())) } @@ -902,6 +929,15 @@ impl UserID { /// See [conventional User ID] for more information. /// /// [conventional User ID]: #conventional-user-ids + pub fn uri2(&self) -> Result<Option<&str>> { + Ok(self.do_parse()?.uri()) + } + + /// Parses the User ID according to de facto conventions, and + /// returns the URI, if any. + /// + /// Like [`UserID::uri2`], but heap-allocates. + #[deprecated(note = "Use UserID::uri2")] pub fn uri(&self) -> Result<Option<String>> { Ok(self.do_parse()?.uri().map(|s| s.to_string())) } @@ -925,10 +961,9 @@ impl UserID { /// [empty locale]: https://www.w3.org/International/wiki/Case_folding /// [Autocrypt]: https://autocrypt.org/level1.html#e-mail-address-canonicalization pub fn email_normalized(&self) -> Result<Option<String>> { - match self.email() { - e @ Err(_) => e, - Ok(None) => Ok(None), - Ok(Some(address)) => { + match self.email2()? { + None => Ok(None), + Some(address) => { let mut iter = address.split('@'); let localpart = iter.next().expect("Invalid email address"); let domain = iter.next().expect("Invalid email address"); |