From 8987c5963bda650dc766bd43a4e001ea0ce283a7 Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Wed, 29 Apr 2020 12:26:17 +0200 Subject: openpgp: Reduce visibility of MessageValidator. - Make MessageValidator `pub(crate)` instead of `pub`. - Move doctests into unit tests as doctests cannot access `pub(crate)` APIs. - Fixes #490. --- openpgp/src/message/mod.rs | 237 +++++++++++++-------------------------------- 1 file changed, 66 insertions(+), 171 deletions(-) (limited to 'openpgp/src/message/mod.rs') diff --git a/openpgp/src/message/mod.rs b/openpgp/src/message/mod.rs index 747d2b89..cc3b6508 100644 --- a/openpgp/src/message/mod.rs +++ b/openpgp/src/message/mod.rs @@ -122,19 +122,8 @@ impl MessageValidity { } /// Used to help validate a packet sequence is a valid OpenPGP message. -/// -/// ```rust -/// # extern crate sequoia_openpgp as openpgp; -/// use openpgp::message::{MessageValidator, MessageValidity, Token}; -/// -/// let mut l = MessageValidator::new(); -/// l.push_token(Token::Literal, &[0]); -/// l.finish(); -/// -/// assert!(if let MessageValidity::Message = l.check() { true } else { false }); -/// ``` #[derive(Debug)] -pub struct MessageValidator { +pub(crate) struct MessageValidator { tokens: Vec, finished: bool, // Once a raw token is pushed, this is set to None and pushing @@ -162,102 +151,6 @@ impl MessageValidator { } } - /// Returns whether the packet sequence is a valid message. - /// - /// Note: a `MessageValidator` will only return this after - /// `MessageValidator::finish` has been called. - /// - /// # Examples - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::MessageValidator; - /// use openpgp::packet::Tag; - /// - /// let mut l = MessageValidator::new(); - /// l.push(Tag::Literal, &[0]); - /// - /// // Note: Even though we've read the whole message, because `finish` hasn't been called, - /// // `l.is_message()` still returns false. - /// assert!(!l.is_message()); - /// - /// l.finish(); - /// - /// // After `l.finish()` has been called the packet sequence is considered to ba a valid message. - /// assert!(l.is_message()); - /// ``` - pub fn is_message(&self) -> bool { - self.check().is_message() - } - - /// Returns whether the packet sequence forms a valid message - /// prefix. - /// - /// Note: a `MessageValidator` will only return this before - /// `MessageValidator::finish` has been called. - /// - /// # Examples - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::MessageValidator; - /// use openpgp::packet::Tag; - /// - /// let mut l = MessageValidator::new(); - /// l.push(Tag::Literal, &[0]); - /// - /// // Note: Even though we've read the whole message, because `finish` hasn't been called, - /// // `l.is_message()` still returns false. - /// assert!(!l.is_message()); - /// - /// // `l.is_message_prefix()` returns true because this is a valid message prefix. - /// assert!(l.is_message_prefix()); - /// ``` - pub fn is_message_prefix(&self) -> bool { - self.check().is_message_prefix() - } - - /// Returns whether the packet sequence is definitely not a valid - /// OpenPGP Message. - /// - /// # Examples - /// - /// When the packet sequence is too short the validator will report an error. - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::MessageValidator; - /// - /// let mut l = MessageValidator::new(); - /// - /// // Note: `l.is_err()` will not return true if this still can be a valid message prefix. - /// assert!(!l.is_err()); - /// - /// l.finish(); - /// - /// // Now that the packet sequence has been marked as finished `l.is_err()` will return true. - /// assert!(l.is_err()); - /// ``` - /// - /// When an unexpected packet is encountered the validator will report an error - /// early. - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::MessageValidator; - /// use openpgp::packet::Tag; - /// - /// let mut l = MessageValidator::new(); - /// l.push(Tag::UserID, &[0]); - /// - /// // `l.is_err()` will return true even though `l.finish()` has not been called as this - /// // is definitely not a valid message prefix. - /// assert!(l.is_err()); - /// ``` - pub fn is_err(&self) -> bool { - self.check().is_err() - } - /// Adds a token to the token stream. #[cfg(test)] pub(crate) fn push_raw(&mut self, token: Token) { @@ -281,19 +174,6 @@ impl MessageValidator { /// /// Note: the token *must* correspond to a packet; this function /// will panic if `token` is `Token::Pop`. - /// - /// # Examples - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::{MessageValidator, MessageValidity, Token}; - /// - /// let mut l = MessageValidator::new(); - /// l.push_token(Token::Literal, &[0]); - /// l.finish(); - /// - /// assert!(if let MessageValidity::Message = l.check() { true } else { false }); - /// ``` pub fn push_token(&mut self, token: Token, path: &[usize]) { assert!(!self.finished); assert!(self.depth.is_some()); @@ -325,20 +205,6 @@ impl MessageValidator { /// Unlike `push_token`, this function does not automatically /// account for changes in the depth. If you use this function /// directly, you must push any required `Token::Pop` tokens. - /// - /// # Examples - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::{MessageValidator, MessageValidity}; - /// use openpgp::packet::Tag; - /// - /// let mut l = MessageValidator::new(); - /// l.push(Tag::Literal, &[0]); - /// l.finish(); - /// - /// assert!(if let MessageValidity::Message = l.check() { true } else { false }); - /// ``` pub fn push(&mut self, tag: Tag, path: &[usize]) { if self.error.is_some() { return; @@ -375,18 +241,6 @@ impl MessageValidator { } /// Note that the entire message has been seen. - /// - /// # Examples - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::{MessageValidator, MessageValidity}; - /// - /// let mut l = MessageValidator::new(); - /// l.finish(); - /// - /// assert!(if let MessageValidity::Error(_) = l.check() { true } else { false }); - /// ``` pub fn finish(&mut self) { assert!(!self.finished); @@ -413,29 +267,6 @@ impl MessageValidator { /// MessageValidity::MessagePrefix or MessageValidity::Error. Once /// MessageValidity::finish() has been called, then only /// MessageValidity::Message or MessageValidity::Error will be returned. - /// - /// # Examples - /// - /// ```rust - /// # extern crate sequoia_openpgp as openpgp; - /// use openpgp::message::{MessageValidator, MessageValidity}; - /// use openpgp::packet::Tag; - /// - /// // No packets will return an error. - /// let mut l = MessageValidator::new(); - /// assert!(if let MessageValidity::MessagePrefix = l.check() { true } else { false }); - /// l.finish(); - /// - /// assert!(if let MessageValidity::Error(_) = l.check() { true } else { false }); - /// - /// // Simple one-literal message. - /// let mut l = MessageValidator::new(); - /// l.push(Tag::Literal, &[0]); - /// assert!(if let MessageValidity::MessagePrefix = l.check() { true } else { false }); - /// l.finish(); - /// - /// assert!(if let MessageValidity::Message = l.check() { true } else { false }); - /// ``` pub fn check(&self) -> MessageValidity { if let Some(ref err) = self.error { return MessageValidity::Error((*err).clone().into()); @@ -463,7 +294,7 @@ impl MessageValidator { } } } - + // DOC-HACK: To avoid having a top-level re-export of `Cert`, we move // it in a submodule `def`. pub use def::Message; @@ -1366,4 +1197,68 @@ mod tests { fn f(_: T) {} f(Message::try_from(vec![])); } + + #[test] + fn basic_message_validator() { + use crate::message::{MessageValidator, MessageValidity, Token}; + + let mut l = MessageValidator::new(); + l.push_token(Token::Literal, &[0]); + l.finish(); + assert!(if let MessageValidity::Message = l.check() { true } else { false }); + } + + #[test] + fn message_validator_push_token() { + use crate::message::{MessageValidator, MessageValidity, Token}; + + let mut l = MessageValidator::new(); + l.push_token(Token::Literal, &[0]); + l.finish(); + + assert!(if let MessageValidity::Message = l.check() { true } else { false }); + } + + #[test] + fn message_validator_push() { + use crate::message::{MessageValidator, MessageValidity}; + use crate::packet::Tag; + + let mut l = MessageValidator::new(); + l.push(Tag::Literal, &[0]); + l.finish(); + + assert!(if let MessageValidity::Message = l.check() { true } else { false }); + } + + #[test] + fn message_validator_finish() { + use crate::message::{MessageValidator, MessageValidity}; + + let mut l = MessageValidator::new(); + l.finish(); + + assert!(if let MessageValidity::Error(_) = l.check() { true } else { false }); + } + + #[test] + fn message_validator_check() { + use crate::message::{MessageValidator, MessageValidity}; + use crate::packet::Tag; + + // No packets will return an error. + let mut l = MessageValidator::new(); + assert!(if let MessageValidity::MessagePrefix = l.check() { true } else { false }); + l.finish(); + + assert!(if let MessageValidity::Error(_) = l.check() { true } else { false }); + + // Simple one-literal message. + let mut l = MessageValidator::new(); + l.push(Tag::Literal, &[0]); + assert!(if let MessageValidity::MessagePrefix = l.check() { true } else { false }); + l.finish(); + + assert!(if let MessageValidity::Message = l.check() { true } else { false }); + } } -- cgit v1.2.3