diff options
-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) => { |