diff options
author | Neal H. Walfield <neal@pep.foundation> | 2018-11-22 11:39:12 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2018-11-22 11:45:50 +0100 |
commit | d736dcfa9ae297dee9d91428d73496969daa10a8 (patch) | |
tree | 131d9b5ba8d48f764e002c6a61f7950ba357c5cf /openpgp/src | |
parent | 26829fc5e240fd60c1d8aae1c39097e61fe436ed (diff) |
openpgp: Detect ASCII-Armored data and decode.
- Add a basic check to the PacketParserBuilder to see if the message
could be a binary OpenPGP message. If not, push an ASCII-Armor
decoder.
Diffstat (limited to 'openpgp/src')
-rw-r--r-- | openpgp/src/parse/packet_parser_builder.rs | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/openpgp/src/parse/packet_parser_builder.rs b/openpgp/src/parse/packet_parser_builder.rs index 2f927291..73c20d8a 100644 --- a/openpgp/src/parse/packet_parser_builder.rs +++ b/openpgp/src/parse/packet_parser_builder.rs @@ -14,6 +14,7 @@ use parse::PacketParserState; use parse::PacketParserSettings; use parse::ParserResult; use parse::Cookie; +use armor; /// A builder for configuring a `PacketParser`. /// @@ -118,12 +119,33 @@ impl<'a> PacketParserBuilder<'a> { /// # return Ok(ppr); /// # } /// ``` - pub fn finalize(self) + pub fn finalize(mut self) -> Result<PacketParserResult<'a>> where Self: 'a { let state = PacketParserState::new(self.settings); + // If the first byte does not have the high-bit set, it is + // definitely not a binary OpenPGP message. Since an + // ASCII-armor message never has a high-bit set, there is a + // good chance that the message is armored. + // + // This heuristic doesn't work if the message is + // ASCII-armored, but the armored data is preceded by + // non-ASCII UTF-8, which sets the high bit. In such cases we + // will fail to push an armor decoder. + let armored = { + let data = self.bio.data(1)?; + data.len() > 0 && ((data[0] as i8) > 0) + }; + + if armored { + self.bio = Box::new(BufferedReaderGeneric::with_cookie( + armor::Reader::from_buffered_reader(self.bio, None), + None, + Default::default())); + } + // Parse the first packet. match PacketParser::parse(Box::new(self.bio), state, vec![ 0 ])? { ParserResult::Success(mut pp) => { |