summaryrefslogtreecommitdiffstats
path: root/openpgp/src/regex
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2021-01-19 15:11:49 +0100
committerNeal H. Walfield <neal@pep.foundation>2021-01-19 17:19:20 +0100
commitd68abdb17b621fd3997a263ce8a95450f109b931 (patch)
tree8dba51ef012f8f7c09d68164eb2025ae385e607d /openpgp/src/regex
parente13677838f65e5ec6d1624ec10de36b2771efcd4 (diff)
openpgp: Keep track of regular expressions that match everything.
- When scoping a trust path, it is helpful to know when a `RegexSet` matches everything, i.e., when it doesn't constrain the path. - Add `RegexSet::everything` to create such a `RegexSet`, tweak `RegexSet::new` to identify the common case (no regular expressions supplied), and add `RegexSet::matches_everything` to return whether that is the case. - Note: the heuristic in `Regex::new` does doesn't identify all regular expressions that match everything.
Diffstat (limited to 'openpgp/src/regex')
-rw-r--r--openpgp/src/regex/mod.rs74
1 files changed, 67 insertions, 7 deletions
diff --git a/openpgp/src/regex/mod.rs b/openpgp/src/regex/mod.rs
index b3de4f78..90487dd2 100644
--- a/openpgp/src/regex/mod.rs
+++ b/openpgp/src/regex/mod.rs
@@ -496,6 +496,7 @@ impl Regex {
enum RegexSet_ {
Regex(Regex),
Invalid,
+ Everything,
}
assert_send_and_sync!(RegexSet_);
@@ -615,13 +616,7 @@ impl RegexSet {
// Match everything.
t!("No regular expressions provided.");
Ok(RegexSet {
- re_set: RegexSet_::Regex(
- Regex {
- regex: regex::RegexBuilder::new(
- &Hir::empty().to_string())
- .build()?,
- disable_sanitizations: false,
- }),
+ re_set: RegexSet_::Everything,
disable_sanitizations: false,
})
} else {
@@ -850,6 +845,69 @@ impl RegexSet {
Self::from_bytes(sig.regular_expressions())
}
+ /// Returns a `RegexSet` that matches everything.
+ ///
+ /// Note: sanitizations are still enabled. So, to really match
+ /// everything, you still need to call
+ /// [`RegexSet::disable_sanitizations`].
+ ///
+ /// [`RegexSet::disable_sanitizations`]: #method.disable_sanitizations
+ ///
+ /// This can be used to optimize the evaluation of scoping rules
+ /// along a path: if a `RegexSet` matches everything, then it
+ /// doesn't further contrain the path.
+ pub fn everything() -> Result<Self>
+ {
+ Ok(Self {
+ re_set: RegexSet_::Everything,
+ disable_sanitizations: false,
+ })
+ }
+
+ /// Returns whether a `RegexSet` matches everything.
+ ///
+ /// Normally, this only returns true if the `RegexSet` was created
+ /// using [`RegexSet::everything`]. [`RegexSet::new`],
+ /// [`RegexSet::from_bytes`], [`RegexSet::from_signature`] do
+ /// detect some regular expressions that match everything (e.g.,
+ /// if no regular expressions are supplied). But, they do not
+ /// guarantee that a `RegexSet` containing a regular expression
+ /// like `.?`, which does in fact match everything, is detected as
+ /// matching everything.
+ ///
+ /// [`RegexSet::everything`]: #method.everything
+ /// [`RegexSet::new`]: #method.everything
+ /// [`RegexSet::from_bytes`]: #method.from_bytes
+ /// [`RegexSet::from_signature`]: #method.from_signature
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use sequoia_openpgp as openpgp;
+ /// use openpgp::regex::RegexSet;
+ ///
+ /// # fn main() -> openpgp::Result<()> {
+ /// assert!(RegexSet::everything()?.matches_everything());
+ /// let empty: &[ &str ] = &[];
+ /// assert!(RegexSet::new(empty.iter())?.matches_everything());
+ ///
+ /// // A regular expression that matches everything. But
+ /// // `RegexSet` returns false, because it can't detect it.
+ /// let res: &[ &str ] = &[
+ /// &".?"[..],
+ /// ];
+ /// let re_set = RegexSet::new(res.into_iter())?;
+ /// assert!(! re_set.matches_everything());
+ /// # Ok(()) }
+ /// ```
+ pub fn matches_everything(&self) -> bool {
+ if let RegexSet_::Everything = self.re_set {
+ true
+ } else {
+ false
+ }
+ }
+
/// Controls whether strings with control characters are allowed.
///
/// If `false` (the default), i.e., sanity checks are enabled, and
@@ -916,6 +974,8 @@ impl RegexSet {
re.is_match_clean(s),
RegexSet_::Invalid =>
false,
+ RegexSet_::Everything =>
+ true,
}
}