From b20d708952f0031273068f1d0d20aec640d31857 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Mon, 4 Dec 2023 15:38:24 +0100 Subject: 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. --- openpgp/src/packet/unknown.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'openpgp') 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::() { + e.clone().into() + } else if let Some(e) = self.error.downcast_ref::() { + 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(), } } -- cgit v1.2.3