diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-12-04 15:38:24 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-12-05 15:47:10 +0100 |
commit | b20d708952f0031273068f1d0d20aec640d31857 (patch) | |
tree | 7e48b3eb9b6fb7688c85dc155cbf2c1cb8362fc4 | |
parent | 4205c4377531006a53d611828279934961ab2fa2 (diff) |
openpgp: Preserve more information when cloning packet::Unknown.
- anyhow::Error isn't Clone, so we cannot, in general, duplicate the
error without losing information. We can try to downcast to the
most likely errors, and clone them, but this can never cover all
possibilities.
- Further, the error wrapped in std::io::Error isn't clone, so we
necessarily lose information when cloning this, even after we
changed Sequoia to return concrete errors.
- I think this is the best we can do, at least for now.
- Fixes #1068.
-rw-r--r-- | openpgp/src/packet/unknown.rs | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/openpgp/src/packet/unknown.rs b/openpgp/src/packet/unknown.rs index e7d82afa..48b7da1e 100644 --- a/openpgp/src/packet/unknown.rs +++ b/openpgp/src/packet/unknown.rs @@ -56,7 +56,33 @@ impl Clone for Unknown { Unknown { common: self.common.clone(), tag: self.tag, - error: anyhow::anyhow!("{}", self.error), + error: { + // anyhow::Error isn't Clone, so we cannot, in + // general, duplicate the error without losing + // information. We can try to downcast to the most + // likely errors, and clone them, but this can never + // cover all possibilities. + use std::io; + + if let Some(e) = self.error.downcast_ref::<crate::Error>() { + e.clone().into() + } else if let Some(e) = self.error.downcast_ref::<io::Error>() { + if let Some(wrapped) = e.get_ref() { + // The wrapped error isn't clone, so this + // loses information here. This will always + // be lossy, even once we changed this crate + // to return concrete errors. + io::Error::new(e.kind(), wrapped.to_string()).into() + } else { + io::Error::from(e.kind()).into() + } + } else { + // Here, we lose information, but the conversion + // was lossy before. + crate::Error::InvalidOperation(self.error.to_string()) + .into() + } + }, container: self.container.clone(), } } |