diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-08-07 14:22:43 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-08-07 14:24:32 +0200 |
commit | 24529e03b55f29cf7f735d6208de09a7352db113 (patch) | |
tree | a7c108ceb67e17300e4e7b1449ad428f5719cdbe /openpgp/src/parse.rs | |
parent | 19cef0decc102e01d85bdb727337734926ed6ef1 (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.
Diffstat (limited to 'openpgp/src/parse.rs')
-rw-r--r-- | openpgp/src/parse.rs | 46 |
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(()) + } } |