summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-12-04 15:38:24 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-12-05 15:47:10 +0100
commitb20d708952f0031273068f1d0d20aec640d31857 (patch)
tree7e48b3eb9b6fb7688c85dc155cbf2c1cb8362fc4
parent4205c4377531006a53d611828279934961ab2fa2 (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.rs28
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(),
}
}