dirmgr: eliminate StringParsingError.

It had too many possible Kinds depending on what kind of string had
failed to parse.

I decided to use #[source] here instead of #[from], so that we
would have to explicitly convert these errors where they show up.
This commit is contained in:
Nick Mathewson 2022-02-16 16:02:28 -05:00
parent f71473cf73
commit 4bb7c97399
4 changed files with 23 additions and 29 deletions

View File

@ -177,7 +177,8 @@ async fn download_attempt<R: Runtime>(
let missing = state.missing_docs();
let fetched = fetch_multiple(Arc::clone(dirmgr), missing, parallelism).await?;
for (client_req, dir_response) in fetched {
let text = String::from_utf8(dir_response.into_output())?;
let text =
String::from_utf8(dir_response.into_output()).map_err(Error::BadUtf8FromDirectory)?;
match dirmgr.expand_response_text(&client_req, text) {
Ok(text) => {
let outcome = state.add_from_download(&text, &client_req, Some(&dirmgr.store));

View File

@ -49,9 +49,15 @@ pub enum Error {
/// An error given by the consensus diff crate.
#[error("consdiff error: {0}")]
ConsensusDiffError(#[from] tor_consdiff::Error),
/// A string parsing error.
#[error("string parsing error: {0}")]
StringParsingError(String),
/// Invalid UTF8 in directory response.
#[error("invalid utf-8 from directory server")]
BadUtf8FromDirectory(#[source] std::string::FromUtf8Error),
/// Invalid UTF8 from our cache.
#[error("Invalid utf-8 in directory cache")]
BadUtf8InCache(#[source] std::str::Utf8Error),
/// Invalid hexadecimal value in the cache.
#[error("Invalid hexadecimal id in directory cache")]
BadHexInCache(#[source] hex::FromHexError),
/// An error given by the network document crate.
#[error("netdoc error: {0}")]
NetDocError(#[from] tor_netdoc::Error),
@ -83,24 +89,6 @@ pub enum Error {
Bug(#[from] tor_error::Bug),
}
impl From<std::str::Utf8Error> for Error {
fn from(err: std::str::Utf8Error) -> Self {
Error::StringParsingError(err.to_string())
}
}
impl From<std::string::FromUtf8Error> for Error {
fn from(err: std::string::FromUtf8Error) -> Self {
Error::StringParsingError(err.to_string())
}
}
impl From<hex::FromHexError> for Error {
fn from(err: hex::FromHexError) -> Self {
Error::StringParsingError(err.to_string())
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::IOError(Arc::new(err))
@ -147,13 +135,15 @@ impl HasKind for Error {
E::UnrecognizedSchema => EK::CacheCorrupted,
E::BadNetworkConfig(_) => EK::InvalidConfig,
E::DirectoryNotPresent => EK::DirectoryExpired,
E::BadUtf8FromDirectory(_) => EK::TorProtocolViolation,
E::BadUtf8InCache(_) => EK::CacheCorrupted,
E::BadHexInCache(_) => EK::CacheCorrupted,
E::UnrecognizedAuthorities => EK::TorProtocolViolation,
E::ManagerDropped => EK::TorShuttingDown,
E::CantAdvanceState => EK::DirectoryStalled,
E::StorageError(_) => EK::CacheAccessFailed,
E::ConsensusDiffError(_) => EK::TorProtocolViolation,
E::StringParsingError(_) => todo!(), //TODO: refactor.
E::NetDocError(_) => todo!(), // TODO: depends on source
E::NetDocError(_) => todo!(), // TODO: depends on source
E::DirClientError(e) => e.kind(),
E::SignatureError(_) => EK::TorProtocolViolation,
E::IOError(_) => EK::CacheAccessFailed,

View File

@ -229,7 +229,7 @@ impl<DM: WriteNetDir> DirState for GetConsensusState<DM> {
_ => return Err(Error::Unwanted("Not an md consensus")),
};
self.add_consensus_text(true, text.as_str()?)
self.add_consensus_text(true, text.as_str().map_err(Error::BadUtf8InCache)?)
.map(|meta| meta.is_some())
}
fn add_from_download(
@ -398,7 +398,8 @@ impl<DM: WriteNetDir> DirState for GetCertsState<DM> {
// our input and remembering them.
for id in &self.missing_docs() {
if let Some(cert) = docs.get(id) {
let parsed = AuthCert::parse(cert.as_str()?)?.check_signature()?;
let parsed = AuthCert::parse(cert.as_str().map_err(Error::BadUtf8InCache)?)?
.check_signature()?;
let now = current_time(&self.writedir)?;
if let Ok(cert) = parsed.check_valid_at(&now) {
self.missing_certs.remove(cert.key_ids());
@ -740,7 +741,7 @@ impl<DM: WriteNetDir> DirState for GetMicrodescsState<DM> {
warn!("Bug: loaded a microdesc that we didn't want from the cache.");
continue;
}
if let Ok(md) = Microdesc::parse(text.as_str()?) {
if let Ok(md) = Microdesc::parse(text.as_str().map_err(Error::BadUtf8InCache)?) {
if md.digest() == &digest {
microdescs.push(md);
continue;

View File

@ -677,7 +677,8 @@ impl Drop for Unlinker {
/// Convert a hexadecimal sha3-256 digest from the database into an array.
fn digest_from_hex(s: &str) -> Result<[u8; 32]> {
hex::decode(s)?
hex::decode(s)
.map_err(Error::BadHexInCache)?
.try_into()
.map_err(|_| Error::CacheCorruption("Invalid digest in database"))
}
@ -686,7 +687,8 @@ fn digest_from_hex(s: &str) -> Result<[u8; 32]> {
/// digest column from the database into an array.
fn digest_from_dstr(s: &str) -> Result<[u8; 32]> {
if let Some(stripped) = s.strip_prefix("sha3-256-") {
hex::decode(stripped)?
hex::decode(stripped)
.map_err(Error::BadHexInCache)?
.try_into()
.map_err(|_| Error::CacheCorruption("Invalid digest in database"))
} else {