diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-12-19 13:23:53 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-12-20 18:04:56 +0100 |
commit | 103379888e9d0ccc701a24f2adb539bc9095f10b (patch) | |
tree | a620c1788f82c9f4bda9a0a1e94aec9ccfc32476 /openpgp/src | |
parent | dc578999ea706417f4fd1a877ecc06840e58d5b0 (diff) |
openpgp: Store literal data in struct Literal.
- With this change, packet::Common is only used by container
packets.
Diffstat (limited to 'openpgp/src')
-rw-r--r-- | openpgp/src/armor.rs | 2 | ||||
-rw-r--r-- | openpgp/src/packet/literal.rs | 33 | ||||
-rw-r--r-- | openpgp/src/packet/mod.rs | 4 | ||||
-rw-r--r-- | openpgp/src/packet_pile.rs | 25 | ||||
-rw-r--r-- | openpgp/src/parse/parse.rs | 55 | ||||
-rw-r--r-- | openpgp/src/serialize/mod.rs | 11 | ||||
-rw-r--r-- | openpgp/src/serialize/padding.rs | 2 |
7 files changed, 81 insertions, 51 deletions
diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs index 0a3282a4..ea2ee3b7 100644 --- a/openpgp/src/armor.rs +++ b/openpgp/src/armor.rs @@ -471,7 +471,7 @@ impl<'a> Reader<'a> { /// reader.read_to_end(&mut buf)?; /// /// let message = Message::from_bytes(&buf)?; - /// assert_eq!(message.body().unwrap().body().unwrap(), + /// assert_eq!(message.body().unwrap().body(), /// b"Hello world!"); /// # Ok(()) /// # } diff --git a/openpgp/src/packet/literal.rs b/openpgp/src/packet/literal.rs index fa97d3e3..51ea84ad 100644 --- a/openpgp/src/packet/literal.rs +++ b/openpgp/src/packet/literal.rs @@ -36,6 +36,11 @@ pub struct Literal { /// A four-octet number that indicates a date associated with the /// literal data. date: Option<Timestamp>, + /// The literal data. + /// + /// This is written when serialized, and set by the packet parser + /// if `buffer_unread_content` is used. + body: Vec<u8>, } impl fmt::Debug for Literal { @@ -46,19 +51,13 @@ impl fmt::Debug for Literal { None }; - let body = if let Some(ref body) = self.common.body { - &body[..] - } else { - &b""[..] - }; - let threshold = 36; - let prefix = &body[..cmp::min(threshold, body.len())]; + let prefix = &self.body[..cmp::min(threshold, self.body.len())]; let mut prefix_fmt = String::from_utf8_lossy(prefix).into_owned(); - if body.len() > threshold { + if self.body.len() > threshold { prefix_fmt.push_str("..."); } - prefix_fmt.push_str(&format!(" ({} bytes)", body.len())[..]); + prefix_fmt.push_str(&format!(" ({} bytes)", self.body.len())[..]); f.debug_struct("Literal") .field("format", &self.format) @@ -77,17 +76,23 @@ impl Literal { format: format, filename: None, date: None, + body: Vec::with_capacity(0), } } - /// Gets the Literal packet's body. - pub fn body(&self) -> Option<&[u8]> { - self.common.body.as_ref().map(|b| b.as_slice()) + /// Gets a reference to the Literal packet's body. + pub fn body(&self) -> &[u8] { + &self.body + } + + /// Gets a mutable reference to the Literal packet's body. + pub fn body_mut(&mut self) -> &mut Vec<u8> { + &mut self.body } - /// Sets the Literal packet's body to the provided byte string. + /// Sets the Literal packet's body. pub fn set_body(&mut self, data: Vec<u8>) -> Vec<u8> { - self.common.set_body(data) + std::mem::replace(&mut self.body, data) } /// Gets the Literal packet's content disposition. diff --git a/openpgp/src/packet/mod.rs b/openpgp/src/packet/mod.rs index fb1cf2a6..4cee893d 100644 --- a/openpgp/src/packet/mod.rs +++ b/openpgp/src/packet/mod.rs @@ -146,7 +146,9 @@ pub struct Common { /// [`Signature`]: ../packet/signature/struct.Signature.html /// /// - One packet, the literal data packet, includes unstructured - /// data. That data can be stored here. + /// data. That data is stored in [`Literal`]. + /// + /// [`Literal`]: ../packet/struct.Literal.html /// /// - Some packets are containers. If the parser does not parse /// the packet's child, either because the caller used diff --git a/openpgp/src/packet_pile.rs b/openpgp/src/packet_pile.rs index cc3d04da..a290f841 100644 --- a/openpgp/src/packet_pile.rs +++ b/openpgp/src/packet_pile.rs @@ -200,7 +200,7 @@ impl PacketPile { /// [ literal.into() ].to_vec()) /// .unwrap(); /// # if let Some(Packet::Literal(lit)) = pile.path_ref(&[0, 0]) { - /// # assert_eq!(lit.body(), Some(&b"new"[..]), "{:#?}", lit); + /// # assert_eq!(lit.body(), &b"new"[..], "{:#?}", lit); /// # } else { /// # panic!("Unexpected packet!"); /// # } @@ -661,10 +661,18 @@ mod test { assert_eq!(pile.path_ref_mut(&[ 0, 0, i ]).unwrap().tag(), Tag::Literal); - assert_eq!(pile.path_ref(&[ 0, 0, i ]).unwrap().body(), - Some(t)); - assert_eq!(pile.path_ref_mut(&[ 0, 0, i ]).unwrap().body(), - Some(t)); + let packet = pile.path_ref(&[ 0, 0, i ]).unwrap(); + if let Packet::Literal(l) = packet { + assert_eq!(l.body(), t); + } else { + panic!("Expected literal, got: {:?}", packet); + } + let packet = pile.path_ref_mut(&[ 0, 0, i ]).unwrap(); + if let Packet::Literal(l) = packet { + assert_eq!(l.body(), t); + } else { + panic!("Expected literal, got: {:?}", packet); + } } // Try a few out of bounds accesses. @@ -717,8 +725,7 @@ mod test { let children = pile.into_children().collect::<Vec<Packet>>(); assert_eq!(children.len(), 1, "{:#?}", children); if let Packet::Literal(ref literal) = children[0] { - assert_eq!(literal.body(), Some(&b"two"[..]), - "{:#?}", literal); + assert_eq!(literal.body(), &b"two"[..], "{:#?}", literal); } else { panic!("WTF"); } @@ -755,7 +762,7 @@ mod test { .children() .map(|p| { if let Packet::Literal(ref literal) = p { - literal.body().unwrap() + literal.body() } else { panic!("Expected a literal packet, got: {:?}", p); } @@ -812,7 +819,7 @@ mod test { .children() .map(|p| { if let Packet::Literal(ref literal) = p { - literal.body().unwrap() + literal.body() } else { panic!("Expected a literal packet, got: {:?}", p); } diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse/parse.rs index 33b27d1a..e7b1e293 100644 --- a/openpgp/src/parse/parse.rs +++ b/openpgp/src/parse/parse.rs @@ -3586,9 +3586,12 @@ impl <'a> PacketParser<'a> { /// .starts_with(b"A Cypherpunk's Manifesto")); /// # assert!(pp.buffer_unread_content()? /// # .starts_with(b"A Cypherpunk's Manifesto")); - /// assert!(pp.packet.body().unwrap() - /// .starts_with(b"A Cypherpunk's Manifesto")); - /// assert_eq!(pp.packet.body().unwrap().len(), 5158); + /// if let Packet::Literal(l) = &pp.packet { + /// assert!(l.body().starts_with(b"A Cypherpunk's Manifesto")); + /// assert_eq!(l.body().len(), 5158); + /// } else { + /// unreachable!(); + /// } /// } /// /// // Start parsing the next packet. @@ -3598,18 +3601,33 @@ impl <'a> PacketParser<'a> { /// # } pub fn buffer_unread_content(&mut self) -> Result<&[u8]> { let mut rest = self.steal_eof()?; - if rest.len() > 0 { - if let Some(body) = self.packet.body_mut() { - body.append(&mut rest); - } else { - self.packet.set_body(rest); - } - } + match &mut self.packet { + Packet::Literal(p) => { + if rest.len() > 0 { + if p.body().len() > 0 { + p.body_mut().append(&mut rest); + } else { + p.set_body(rest); + } + } - if let Some(body) = self.packet.body() { - Ok(&body[..]) - } else { - Ok(&b""[..]) + Ok(p.body()) + }, + p => { + if rest.len() > 0 { + if let Some(body) = p.body_mut() { + body.append(&mut rest); + } else { + p.set_body(rest); + } + } + + if let Some(body) = p.body() { + Ok(&body[..]) + } else { + Ok(&b""[..]) + } + }, } } @@ -4252,9 +4270,12 @@ mod test { "{:?}", pp.packet); } else { pp.buffer_unread_content().unwrap(); - assert_eq!(pp.packet.body().unwrap(), - &test.plaintext.content()[..], - "{:?}", pp.packet); + if let Packet::Literal(l) = &pp.packet { + assert_eq!(l.body(), &test.plaintext.content()[..], + "{:?}", pp.packet); + } else { + panic!("Expected literal, got: {:?}", pp.packet); + } } } else { panic!("Expected a Literal packet. Got: {:?}", ppr); diff --git a/openpgp/src/serialize/mod.rs b/openpgp/src/serialize/mod.rs index fe19910c..3bbd9000 100644 --- a/openpgp/src/serialize/mod.rs +++ b/openpgp/src/serialize/mod.rs @@ -1628,7 +1628,7 @@ impl Literal { if write_tag { let len = 1 + (1 + filename.len()) + 4 - + self.body().as_ref().map(|b| b.len()).unwrap_or(0); + + self.body().len(); CTB::new(Tag::Literal).serialize(o)?; BodyLength::Full(len as u32).serialize(o)?; } @@ -1642,12 +1642,7 @@ impl Literal { impl Serialize for Literal { fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> { - let body = if let Some(body) = self.body() { - &body[..] - } else { - &b""[..] - }; - + let body = self.body(); if TRACE { let prefix = &body[..cmp::min(body.len(), 20)]; eprintln!("Literal::serialize({}{}, {} bytes)", @@ -1666,7 +1661,7 @@ impl Serialize for Literal { impl NetLength for Literal { fn net_len(&self) -> usize { 1 + (1 + self.filename().map(|f| f.len()).unwrap_or(0)) + 4 - + self.body().as_ref().map(|b| b.len()).unwrap_or(0) + + self.body().len() } } diff --git a/openpgp/src/serialize/padding.rs b/openpgp/src/serialize/padding.rs index 4b95c09e..3ad70fd6 100644 --- a/openpgp/src/serialize/padding.rs +++ b/openpgp/src/serialize/padding.rs @@ -347,7 +347,7 @@ mod test { } let m = crate::Message::from_bytes(&padded).unwrap(); - assert_eq!(m.body().unwrap().body().unwrap(), &msg[..]); + assert_eq!(m.body().unwrap().body(), &msg[..]); } /// Asserts that no actual compression is done. |