summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-08-07 14:22:43 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-08-07 14:24:32 +0200
commit24529e03b55f29cf7f735d6208de09a7352db113 (patch)
treea7c108ceb67e17300e4e7b1449ad428f5719cdbe
parent19cef0decc102e01d85bdb727337734926ed6ef1 (diff)
openpgp: Fix hashing the packet bodies.
- Previously, data read using io::Read was hashed twice. We implement io::Read using the BufferedReader implementation, which takes care of the hashing. - Fixes #537.
-rw-r--r--openpgp/src/parse.rs46
1 files changed, 43 insertions, 3 deletions
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs
index 30072c85..9ef03594 100644
--- a/openpgp/src/parse.rs
+++ b/openpgp/src/parse.rs
@@ -4598,9 +4598,9 @@ impl <'a> PacketParser<'a> {
/// `BufferedReader` interfaces.
impl<'a> io::Read for PacketParser<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- let v = buffered_reader_generic_read_impl(self, buf)?;
- self.hash_read_content(&buf[..v]);
- Ok(v)
+ // The BufferedReader interface takes care of hashing the read
+ // values.
+ buffered_reader_generic_read_impl(self, buf)
}
}
@@ -5602,4 +5602,44 @@ mod test {
panic!("expected unknown packet, got: {:?}", packet);
}
}
+
+ /// Checks that the content hash is correctly computed whether or
+ /// not the content has been (fully) read.
+ #[test]
+ fn issue_537() -> Result<()> {
+ // Buffer unread content.
+ let ppr0 = PacketParserBuilder::from_bytes(
+ crate::tests::message("literal-mode-b.gpg"))?
+ .buffer_unread_content()
+ .build()?;
+ let pp0 = ppr0.unwrap();
+ let (packet0, _) = pp0.recurse()?;
+
+ // Drop unread content.
+ let ppr1 = PacketParser::from_bytes(
+ crate::tests::message("literal-mode-b.gpg"))?;
+ let pp1 = ppr1.unwrap();
+ let (packet1, _) = pp1.recurse()?;
+
+ // Read content.
+ let ppr2 = PacketParser::from_bytes(
+ crate::tests::message("literal-mode-b.gpg"))?;
+ let mut pp2 = ppr2.unwrap();
+ io::copy(&mut pp2, &mut io::sink())?;
+ let (packet2, _) = pp2.recurse()?;
+
+ // Partially read content.
+ let ppr3 = PacketParser::from_bytes(
+ crate::tests::message("literal-mode-b.gpg"))?;
+ let mut pp3 = ppr3.unwrap();
+ let mut buf = [0];
+ let nread = pp3.read(&mut buf)?;
+ assert_eq!(buf.len(), nread);
+ let (packet3, _) = pp3.recurse()?;
+
+ assert_eq!(packet0, packet1);
+ assert_eq!(packet1, packet2);
+ assert_eq!(packet2, packet3);
+ Ok(())
+ }
}