diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-01-15 09:51:27 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-01-15 11:34:49 +0100 |
commit | de649ea58966273392f4ab09f2bb72bb75650ae2 (patch) | |
tree | 794bc953ade0610d30c373d94b43ad06c8309944 | |
parent | 59a59ac5bf9cc9be2698eb35376c3b58fd483252 (diff) |
net: Make conversion from u8 to Policy fallible.
-rw-r--r-- | ffi/src/net.rs | 9 | ||||
-rw-r--r-- | ffi/src/store.rs | 4 | ||||
-rw-r--r-- | net/src/lib.rs | 30 | ||||
-rw-r--r-- | store/src/backend/mod.rs | 11 |
4 files changed, 38 insertions, 16 deletions
diff --git a/ffi/src/net.rs b/ffi/src/net.rs index f08a3ef0..906f1999 100644 --- a/ffi/src/net.rs +++ b/ffi/src/net.rs @@ -32,10 +32,11 @@ use libc::{c_char, size_t}; use native_tls::Certificate; +use std::convert::TryInto; use std::ptr; use std::slice; -use sequoia_net::KeyServer; +use sequoia_net::{KeyServer, Policy}; use super::error::Status; use super::core::Context; @@ -56,7 +57,7 @@ fn sq_keyserver_new(ctx: *mut Context, policy: u8, uri: *const c_char) -> *mut KeyServer { let ctx = ffi_param_ref_mut!(ctx); ffi_make_fry_from_ctx!(ctx); - let policy = policy.into(); + let policy: Policy = ffi_try!(policy.try_into()); let uri = ffi_param_cstr!(uri).to_string_lossy(); ffi_try_box!(KeyServer::new(policy, &uri)) @@ -76,7 +77,7 @@ fn sq_keyserver_with_cert(ctx: *mut Context, policy: u8, len: size_t) -> *mut KeyServer { let ctx = ffi_param_ref_mut!(ctx); ffi_make_fry_from_ctx!(ctx); - let policy = policy.into(); + let policy: Policy = ffi_try!(policy.try_into()); let uri = ffi_param_cstr!(uri).to_string_lossy(); if cert.is_null() { @@ -103,7 +104,7 @@ fn sq_keyserver_keys_openpgp_org(ctx: *mut Context, policy: u8) -> *mut KeyServer { let ctx = ffi_param_ref_mut!(ctx); ffi_make_fry_from_ctx!(ctx); - let policy = policy.into(); + let policy: Policy = ffi_try!(policy.try_into()); ffi_try_box!(KeyServer::keys_openpgp_org(policy)) } diff --git a/ffi/src/store.rs b/ffi/src/store.rs index 65372d78..e4082d5a 100644 --- a/ffi/src/store.rs +++ b/ffi/src/store.rs @@ -24,11 +24,13 @@ use libc::c_char; +use std::convert::TryInto; use std::ptr; use sequoia_store::{ self, Mapping, MappingIter, Binding, BundleIter, Key, KeyIter, LogIter, Store, }; +use sequoia_net as net; use super::error::Status; use super::core::Context; @@ -196,7 +198,7 @@ fn sq_mapping_open(ctx: *mut Context, -> *mut Mapping { let ctx = ffi_param_ref_mut!(ctx); ffi_make_fry_from_ctx!(ctx); - let policy = policy.into(); + let policy: net::Policy = ffi_try!(policy.try_into()); let realm = ffi_param_cstr!(realm).to_string_lossy(); let name = ffi_param_cstr!(name).to_string_lossy(); diff --git a/net/src/lib.rs b/net/src/lib.rs index dda95da8..450375cf 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -33,7 +33,7 @@ use hyper_tls::HttpsConnector; use native_tls::{Certificate, TlsConnector}; use percent_encoding::{percent_encode, AsciiSet, CONTROLS}; -use std::convert::From; +use std::convert::{From, TryFrom}; use std::fmt; use std::io::Cursor; use url::Url; @@ -114,20 +114,32 @@ impl<'a> From<&'a Policy> for u8 { } } +impl TryFrom<u8> for Policy { + type Error = TryFromU8Error; -// XXX: TryFrom would be nice. -impl From<u8> for Policy { - fn from(policy: u8) -> Self { + fn try_from(policy: u8) -> std::result::Result<Self, Self::Error> { match policy { - 0 => Policy::Offline, - 1 => Policy::Anonymized, - 2 => Policy::Encrypted, - 3 => Policy::Insecure, - n => panic!("Bad network policy: {}", n), + 0 => Ok(Policy::Offline), + 1 => Ok(Policy::Anonymized), + 2 => Ok(Policy::Encrypted), + 3 => Ok(Policy::Insecure), + n => Err(TryFromU8Error(n)), } } } +/// Indicates errors converting `u8` to `Policy`. +#[derive(Debug)] +pub struct TryFromU8Error(u8); + +impl fmt::Display for TryFromU8Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Bad network policy: {}", self.0) + } +} + +impl std::error::Error for TryFromU8Error {} + /// For accessing keyservers using HKP. pub struct KeyServer { client: Box<dyn AClient>, diff --git a/store/src/backend/mod.rs b/store/src/backend/mod.rs index 8e913436..a285d635 100644 --- a/store/src/backend/mod.rs +++ b/store/src/backend/mod.rs @@ -1,6 +1,7 @@ //! Storage backend. use std::cmp; +use std::convert::TryFrom; use std::fmt; use std::io; use std::rc::Rc; @@ -304,7 +305,7 @@ impl MappingServer { if mapping_policy < 0 || mapping_policy > 3 { return Err(super::Error::ProtocolError.into()); } - let mapping_policy = net::Policy::from(mapping_policy as u8); + let mapping_policy = net::Policy::try_from(mapping_policy as u8)?; if mapping_policy != policy { return Err(net::Error::PolicyViolation(mapping_policy) @@ -1112,7 +1113,7 @@ impl node::mapping_iter::Server for MappingIterServer { if network_policy < 0 || network_policy > 3 { fail!(node::Error::SystemError); } - let network_policy = net::Policy::from(network_policy as u8); + let network_policy = sry!(net::Policy::try_from(network_policy as u8)); let mut entry = pry!(results.get().get_result()).init_ok(); entry.set_realm(&realm); @@ -1310,6 +1311,12 @@ impl From<net::Error> for node::Error { } } +impl From<net::TryFromU8Error> for node::Error { + fn from(_: net::TryFromU8Error) -> Self { + node::Error::SystemError + } +} + impl From<io::Error> for node::Error { fn from(_: io::Error) -> Self { node::Error::SystemError |