summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-12-19 13:23:53 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-12-20 18:04:56 +0100
commit103379888e9d0ccc701a24f2adb539bc9095f10b (patch)
treea620c1788f82c9f4bda9a0a1e94aec9ccfc32476 /openpgp
parentdc578999ea706417f4fd1a877ecc06840e58d5b0 (diff)
openpgp: Store literal data in struct Literal.
- With this change, packet::Common is only used by container packets.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/src/armor.rs2
-rw-r--r--openpgp/src/packet/literal.rs33
-rw-r--r--openpgp/src/packet/mod.rs4
-rw-r--r--openpgp/src/packet_pile.rs25
-rw-r--r--openpgp/src/parse/parse.rs55
-rw-r--r--openpgp/src/serialize/mod.rs11
-rw-r--r--openpgp/src/serialize/padding.rs2
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.