From 88204f91df3e01b69e79b89ba029b42a4025d11f Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 21 Mar 2018 00:24:46 +0000 Subject: [PATCH] rust: Implement error types for Rust protover implementation. This will allow us to do actual error handling intra-crate in a more rusty manner, e.g. propogating errors in match statements, conversion between error types, logging messages, etc. * FIXES part of #24031: https://bugs.torproject.org/24031. --- src/rust/protover/errors.rs | 43 +++++++++++++++++++++++++++++++++++ src/rust/protover/lib.rs | 3 +++ src/rust/protover/protover.rs | 6 +++-- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/rust/protover/errors.rs diff --git a/src/rust/protover/errors.rs b/src/rust/protover/errors.rs new file mode 100644 index 0000000000..56473d12e6 --- /dev/null +++ b/src/rust/protover/errors.rs @@ -0,0 +1,43 @@ +// Copyright (c) 2018, The Tor Project, Inc. +// Copyright (c) 2018, isis agora lovecruft +// See LICENSE for licensing information + +//! Various errors which may occur during protocol version parsing. + +use std::fmt; +use std::fmt::Display; + +/// All errors which may occur during protover parsing routines. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[allow(missing_docs)] // See Display impl for error descriptions +pub enum ProtoverError { + Overlap, + LowGreaterThanHigh, + Unparseable, + ExceedsMax, + ExceedsExpansionLimit, + UnknownProtocol, + ExceedsNameLimit, +} + +/// Descriptive error messages for `ProtoverError` variants. +impl Display for ProtoverError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ProtoverError::Overlap + => write!(f, "Two or more (low, high) protover ranges would overlap once expanded."), + ProtoverError::LowGreaterThanHigh + => write!(f, "The low in a (low, high) protover range was greater than high."), + ProtoverError::Unparseable + => write!(f, "The protover string was unparseable."), + ProtoverError::ExceedsMax + => write!(f, "The high in a (low, high) protover range exceeds u32::MAX."), + ProtoverError::ExceedsExpansionLimit + => write!(f, "The protover string would exceed the maximum expansion limit."), + ProtoverError::UnknownProtocol + => write!(f, "A protocol in the protover string we attempted to parse is unknown."), + ProtoverError::ExceedsNameLimit + => write!(f, "An unrecognised protocol name was too long."), + } + } +} diff --git a/src/rust/protover/lib.rs b/src/rust/protover/lib.rs index fe8c0f9bb2..371d1ae58f 100644 --- a/src/rust/protover/lib.rs +++ b/src/rust/protover/lib.rs @@ -22,12 +22,15 @@ //! protocols to develop independently, without having to claim compatibility //! with specific versions of Tor. +#[deny(missing_docs)] + extern crate libc; extern crate smartlist; extern crate external; extern crate tor_allocate; extern crate tor_util; +pub mod errors; mod protover; pub mod ffi; diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs index e5dc69b9a0..8ce182cf1b 100644 --- a/src/rust/protover/protover.rs +++ b/src/rust/protover/protover.rs @@ -13,6 +13,8 @@ use std::u32; use tor_util::strings::NUL_BYTE; +use errors::ProtoverError; + /// The first version of Tor that included "proto" entries in its descriptors. /// Authorities should use this to decide whether to guess proto lines. /// @@ -78,7 +80,7 @@ impl fmt::Display for Proto { /// /// C_RUST_COUPLED: src/or/protover.c `PROTOCOL_NAMES` impl FromStr for Proto { - type Err = &'static str; + type Err = ProtoverError; fn from_str(s: &str) -> Result { match s { @@ -92,7 +94,7 @@ impl FromStr for Proto { "LinkAuth" => Ok(Proto::LinkAuth), "Microdesc" => Ok(Proto::Microdesc), "Relay" => Ok(Proto::Relay), - _ => Err("Not a valid protocol type"), + _ => Err(ProtoverError::UnknownProtocol), } } }