1 /*!
2 Provides routines for extracting literal prefixes and suffixes from an `Hir`.
3 */
4 
5 use std::cmp;
6 use std::fmt;
7 use std::iter;
8 use std::mem;
9 use std::ops;
10 
11 use crate::hir::{self, Hir, HirKind};
12 
13 /// A set of literal byte strings extracted from a regular expression.
14 ///
15 /// Every member of the set is a `Literal`, which is represented by a
16 /// `Vec<u8>`. (Notably, it may contain invalid UTF-8.) Every member is
17 /// said to be either *complete* or *cut*. A complete literal means that
18 /// it extends until the beginning (or end) of the regular expression. In
19 /// some circumstances, this can be used to indicate a match in the regular
20 /// expression.
21 ///
22 /// A key aspect of literal extraction is knowing when to stop. It is not
23 /// feasible to blindly extract all literals from a regular expression, even if
24 /// there are finitely many. For example, the regular expression `[0-9]{10}`
25 /// has `10^10` distinct literals. For this reason, literal extraction is
26 /// bounded to some low number by default using heuristics, but the limits can
27 /// be tweaked.
28 ///
29 /// **WARNING**: Literal extraction uses stack space proportional to the size
30 /// of the `Hir` expression. At some point, this drawback will be eliminated.
31 /// To protect yourself, set a reasonable
32 /// [`nest_limit` on your `Parser`](../../struct.ParserBuilder.html#method.nest_limit).
33 /// This is done for you by default.
34 #[derive(Clone, Eq, PartialEq)]
35 pub struct Literals {
36     lits: Vec<Literal>,
37     limit_size: usize,
38     limit_class: usize,
39 }
40 
41 /// A single member of a set of literals extracted from a regular expression.
42 ///
43 /// This type has `Deref` and `DerefMut` impls to `Vec<u8>` so that all slice
44 /// and `Vec` operations are available.
45 #[derive(Clone, Eq, Ord)]
46 pub struct Literal {
47     v: Vec<u8>,
48     cut: bool,
49 }
50 
51 impl Literals {
52     /// Returns a new empty set of literals using default limits.
53     pub fn empty() -> Literals {
54         Literals { lits: vec![], limit_size: 250, limit_class: 10 }
55     }
56 
57     /// Returns a set of literal prefixes extracted from the given `Hir`.
58     pub fn prefixes(expr: &Hir) -> Literals {
59         let mut lits = Literals::empty();
60         lits.union_prefixes(expr);
61         lits
62     }
63 
64     /// Returns a set of literal suffixes extracted from the given `Hir`.
65     pub fn suffixes(expr: &Hir) -> Literals {
66         let mut lits = Literals::empty();
67         lits.union_suffixes(expr);
68         lits
69     }
70 
71     /// Get the approximate size limit (in bytes) of this set.
72     pub fn limit_size(&self) -> usize {
73         self.limit_size
74     }
75 
76     /// Set the approximate size limit (in bytes) of this set.
77     ///
78     /// If extracting a literal would put the set over this limit, then
79     /// extraction stops.
80     ///
81     /// The new limits will only apply to additions to this set. Existing
82     /// members remain unchanged, even if the set exceeds the new limit.
83     pub fn set_limit_size(&mut self, size: usize) -> &mut Literals {
84         self.limit_size = size;
85         self
86     }
87 
88     /// Get the character class size limit for this set.
89     pub fn limit_class(&self) -> usize {
90         self.limit_class
91     }
92 
93     /// Limits the size of character(or byte) classes considered.
94     ///
95     /// A value of `0` prevents all character classes from being considered.
96     ///
97     /// This limit also applies to case insensitive literals, since each
98     /// character in the case insensitive literal is converted to a class, and
99     /// then case folded.
100     ///
101     /// The new limits will only apply to additions to this set. Existing
102     /// members remain unchanged, even if the set exceeds the new limit.
103     pub fn set_limit_class(&mut self, size: usize) -> &mut Literals {
104         self.limit_class = size;
105         self
106     }
107 
108     /// Returns the set of literals as a slice. Its order is unspecified.
109     pub fn literals(&self) -> &[Literal] {
110         &self.lits
111     }
112 
113     /// Returns the length of the smallest literal.
114     ///
115     /// Returns None is there are no literals in the set.
116     pub fn min_len(&self) -> Option<usize> {
117         let mut min = None;
118         for lit in &self.lits {
119             match min {
120                 None => min = Some(lit.len()),
121                 Some(m) if lit.len() < m => min = Some(lit.len()),
122                 _ => {}
123             }
124         }
125         min
126     }
127 
128     /// Returns true if all members in this set are complete.
129     pub fn all_complete(&self) -> bool {
130         !self.lits.is_empty() && self.lits.iter().all(|l| !l.is_cut())
131     }
132 
133     /// Returns true if any member in this set is complete.
134     pub fn any_complete(&self) -> bool {
135         self.lits.iter().any(|lit| !lit.is_cut())
136     }
137 
138     /// Returns true if this set contains an empty literal.
139     pub fn contains_empty(&self) -> bool {
140         self.lits.iter().any(|lit| lit.is_empty())
141     }
142 
143     /// Returns true if this set is empty or if all of its members is empty.
144     pub fn is_empty(&self) -> bool {
145         self.lits.is_empty() || self.lits.iter().all(|lit| lit.is_empty())
146     }
147 
148     /// Returns a new empty set of literals using this set's limits.
149     pub fn to_empty(&self) -> Literals {
150         let mut lits = Literals::empty();
151         lits.set_limit_size(self.limit_size).set_limit_class(self.limit_class);
152         lits
153     }
154 
155     /// Returns the longest common prefix of all members in this set.
156     pub fn longest_common_prefix(&self) -> &[u8] {
157         if self.is_empty() {
158             return &[];
159         }
160         let lit0 = &*self.lits[0];
161         let mut len = lit0.len();
162         for lit in &self.lits[1..] {
163             len = cmp::min(
164                 len,
165                 lit.iter().zip(lit0).take_while(|&(a, b)| a == b).count(),
166             );
167         }
168         &self.lits[0][..len]
169     }
170 
171     /// Returns the longest common suffix of all members in this set.
172     pub fn longest_common_suffix(&self) -> &[u8] {
173         if self.is_empty() {
174             return &[];
175         }
176         let lit0 = &*self.lits[0];
177         let mut len = lit0.len();
178         for lit in &self.lits[1..] {
179             len = cmp::min(
180                 len,
181                 lit.iter()
182                     .rev()
183                     .zip(lit0.iter().rev())
184                     .take_while(|&(a, b)| a == b)
185                     .count(),
186             );
187         }
188         &self.lits[0][self.lits[0].len() - len..]
189     }
190 
191     /// Returns a new set of literals with the given number of bytes trimmed
192     /// from the suffix of each literal.
193     ///
194     /// If any literal would be cut out completely by trimming, then None is
195     /// returned.
196     ///
197     /// Any duplicates that are created as a result of this transformation are
198     /// removed.
199     pub fn trim_suffix(&self, num_bytes: usize) -> Option<Literals> {
200         if self.min_len().map(|len| len <= num_bytes).unwrap_or(true) {
201             return None;
202         }
203         let mut new = self.to_empty();
204         for mut lit in self.lits.iter().cloned() {
205             let new_len = lit.len() - num_bytes;
206             lit.truncate(new_len);
207             lit.cut();
208             new.lits.push(lit);
209         }
210         new.lits.sort();
211         new.lits.dedup();
212         Some(new)
213     }
214 
215     /// Returns a new set of prefixes of this set of literals that are
216     /// guaranteed to be unambiguous.
217     ///
218     /// Any substring match with a member of the set is returned is guaranteed
219     /// to never overlap with a substring match of another member of the set
220     /// at the same starting position.
221     ///
222     /// Given any two members of the returned set, neither is a substring of
223     /// the other.
224     pub fn unambiguous_prefixes(&self) -> Literals {
225         if self.lits.is_empty() {
226             return self.to_empty();
227         }
228         let mut old: Vec<Literal> = self.lits.iter().cloned().collect();
229         let mut new = self.to_empty();
230         'OUTER: while let Some(mut candidate) = old.pop() {
231             if candidate.is_empty() {
232                 continue;
233             }
234             if new.lits.is_empty() {
235                 new.lits.push(candidate);
236                 continue;
237             }
238             for lit2 in &mut new.lits {
239                 if lit2.is_empty() {
240                     continue;
241                 }
242                 if &candidate == lit2 {
243                     // If the literal is already in the set, then we can
244                     // just drop it. But make sure that cut literals are
245                     // infectious!
246                     candidate.cut = candidate.cut || lit2.cut;
247                     lit2.cut = candidate.cut;
248                     continue 'OUTER;
249                 }
250                 if candidate.len() < lit2.len() {
251                     if let Some(i) = position(&candidate, &lit2) {
252                         candidate.cut();
253                         let mut lit3 = lit2.clone();
254                         lit3.truncate(i);
255                         lit3.cut();
256                         old.push(lit3);
257                         lit2.clear();
258                     }
259                 } else {
260                     if let Some(i) = position(&lit2, &candidate) {
261                         lit2.cut();
262                         let mut new_candidate = candidate.clone();
263                         new_candidate.truncate(i);
264                         new_candidate.cut();
265                         old.push(new_candidate);
266                         candidate.clear();
267                     }
268                 }
269                 // Oops, the candidate is already represented in the set.
270                 if candidate.is_empty() {
271                     continue 'OUTER;
272                 }
273             }
274             new.lits.push(candidate);
275         }
276         new.lits.retain(|lit| !lit.is_empty());
277         new.lits.sort();
278         new.lits.dedup();
279         new
280     }
281 
282     /// Returns a new set of suffixes of this set of literals that are
283     /// guaranteed to be unambiguous.
284     ///
285     /// Any substring match with a member of the set is returned is guaranteed
286     /// to never overlap with a substring match of another member of the set
287     /// at the same ending position.
288     ///
289     /// Given any two members of the returned set, neither is a substring of
290     /// the other.
291     pub fn unambiguous_suffixes(&self) -> Literals {
292         // This is a touch wasteful...
293         let mut lits = self.clone();
294         lits.reverse();
295         let mut unamb = lits.unambiguous_prefixes();
296         unamb.reverse();
297         unamb
298     }
299 
300     /// Unions the prefixes from the given expression to this set.
301     ///
302     /// If prefixes could not be added (for example, this set would exceed its
303     /// size limits or the set of prefixes from `expr` includes the empty
304     /// string), then false is returned.
305     ///
306     /// Note that prefix literals extracted from `expr` are said to be complete
307     /// if and only if the literal extends from the beginning of `expr` to the
308     /// end of `expr`.
309     pub fn union_prefixes(&mut self, expr: &Hir) -> bool {
310         let mut lits = self.to_empty();
311         prefixes(expr, &mut lits);
312         !lits.is_empty() && !lits.contains_empty() && self.union(lits)
313     }
314 
315     /// Unions the suffixes from the given expression to this set.
316     ///
317     /// If suffixes could not be added (for example, this set would exceed its
318     /// size limits or the set of suffixes from `expr` includes the empty
319     /// string), then false is returned.
320     ///
321     /// Note that prefix literals extracted from `expr` are said to be complete
322     /// if and only if the literal extends from the end of `expr` to the
323     /// beginning of `expr`.
324     pub fn union_suffixes(&mut self, expr: &Hir) -> bool {
325         let mut lits = self.to_empty();
326         suffixes(expr, &mut lits);
327         lits.reverse();
328         !lits.is_empty() && !lits.contains_empty() && self.union(lits)
329     }
330 
331     /// Unions this set with another set.
332     ///
333     /// If the union would cause the set to exceed its limits, then the union
334     /// is skipped and it returns false. Otherwise, if the union succeeds, it
335     /// returns true.
336     pub fn union(&mut self, lits: Literals) -> bool {
337         if self.num_bytes() + lits.num_bytes() > self.limit_size {
338             return false;
339         }
340         if lits.is_empty() {
341             self.lits.push(Literal::empty());
342         } else {
343             self.lits.extend(lits.lits);
344         }
345         true
346     }
347 
348     /// Extends this set with another set.
349     ///
350     /// The set of literals is extended via a cross product.
351     ///
352     /// If a cross product would cause this set to exceed its limits, then the
353     /// cross product is skipped and it returns false. Otherwise, if the cross
354     /// product succeeds, it returns true.
355     pub fn cross_product(&mut self, lits: &Literals) -> bool {
356         if lits.is_empty() {
357             return true;
358         }
359         // Check that we make sure we stay in our limits.
360         let mut size_after;
361         if self.is_empty() || !self.any_complete() {
362             size_after = self.num_bytes();
363             for lits_lit in lits.literals() {
364                 size_after += lits_lit.len();
365             }
366         } else {
367             size_after = self.lits.iter().fold(0, |accum, lit| {
368                 accum + if lit.is_cut() { lit.len() } else { 0 }
369             });
370             for lits_lit in lits.literals() {
371                 for self_lit in self.literals() {
372                     if !self_lit.is_cut() {
373                         size_after += self_lit.len() + lits_lit.len();
374                     }
375                 }
376             }
377         }
378         if size_after > self.limit_size {
379             return false;
380         }
381 
382         let mut base = self.remove_complete();
383         if base.is_empty() {
384             base = vec![Literal::empty()];
385         }
386         for lits_lit in lits.literals() {
387             for mut self_lit in base.clone() {
388                 self_lit.extend(&**lits_lit);
389                 self_lit.cut = lits_lit.cut;
390                 self.lits.push(self_lit);
391             }
392         }
393         true
394     }
395 
396     /// Extends each literal in this set with the bytes given.
397     ///
398     /// If the set is empty, then the given literal is added to the set.
399     ///
400     /// If adding any number of bytes to all members of this set causes a limit
401     /// to be exceeded, then no bytes are added and false is returned. If a
402     /// prefix of `bytes` can be fit into this set, then it is used and all
403     /// resulting literals are cut.
404     pub fn cross_add(&mut self, bytes: &[u8]) -> bool {
405         // N.B. This could be implemented by simply calling cross_product with
406         // a literal set containing just `bytes`, but we can be smarter about
407         // taking shorter prefixes of `bytes` if they'll fit.
408         if bytes.is_empty() {
409             return true;
410         }
411         if self.lits.is_empty() {
412             let i = cmp::min(self.limit_size, bytes.len());
413             self.lits.push(Literal::new(bytes[..i].to_owned()));
414             self.lits[0].cut = i < bytes.len();
415             return !self.lits[0].is_cut();
416         }
417         let size = self.num_bytes();
418         if size + self.lits.len() >= self.limit_size {
419             return false;
420         }
421         let mut i = 1;
422         while size + (i * self.lits.len()) <= self.limit_size
423             && i < bytes.len()
424         {
425             i += 1;
426         }
427         for lit in &mut self.lits {
428             if !lit.is_cut() {
429                 lit.extend(&bytes[..i]);
430                 if i < bytes.len() {
431                     lit.cut();
432                 }
433             }
434         }
435         true
436     }
437 
438     /// Adds the given literal to this set.
439     ///
440     /// Returns false if adding this literal would cause the class to be too
441     /// big.
442     pub fn add(&mut self, lit: Literal) -> bool {
443         if self.num_bytes() + lit.len() > self.limit_size {
444             return false;
445         }
446         self.lits.push(lit);
447         true
448     }
449 
450     /// Extends each literal in this set with the character class given.
451     ///
452     /// Returns false if the character class was too big to add.
453     pub fn add_char_class(&mut self, cls: &hir::ClassUnicode) -> bool {
454         self._add_char_class(cls, false)
455     }
456 
457     /// Extends each literal in this set with the character class given,
458     /// writing the bytes of each character in reverse.
459     ///
460     /// Returns false if the character class was too big to add.
461     fn add_char_class_reverse(&mut self, cls: &hir::ClassUnicode) -> bool {
462         self._add_char_class(cls, true)
463     }
464 
465     fn _add_char_class(
466         &mut self,
467         cls: &hir::ClassUnicode,
468         reverse: bool,
469     ) -> bool {
470         use std::char;
471 
472         if self.class_exceeds_limits(cls_char_count(cls)) {
473             return false;
474         }
475         let mut base = self.remove_complete();
476         if base.is_empty() {
477             base = vec![Literal::empty()];
478         }
479         for r in cls.iter() {
480             let (s, e) = (r.start as u32, r.end as u32 + 1);
481             for c in (s..e).filter_map(char::from_u32) {
482                 for mut lit in base.clone() {
483                     let mut bytes = c.to_string().into_bytes();
484                     if reverse {
485                         bytes.reverse();
486                     }
487                     lit.extend(&bytes);
488                     self.lits.push(lit);
489                 }
490             }
491         }
492         true
493     }
494 
495     /// Extends each literal in this set with the byte class given.
496     ///
497     /// Returns false if the byte class was too big to add.
498     pub fn add_byte_class(&mut self, cls: &hir::ClassBytes) -> bool {
499         if self.class_exceeds_limits(cls_byte_count(cls)) {
500             return false;
501         }
502         let mut base = self.remove_complete();
503         if base.is_empty() {
504             base = vec![Literal::empty()];
505         }
506         for r in cls.iter() {
507             let (s, e) = (r.start as u32, r.end as u32 + 1);
508             for b in (s..e).map(|b| b as u8) {
509                 for mut lit in base.clone() {
510                     lit.push(b);
511                     self.lits.push(lit);
512                 }
513             }
514         }
515         true
516     }
517 
518     /// Cuts every member of this set. When a member is cut, it can never
519     /// be extended.
520     pub fn cut(&mut self) {
521         for lit in &mut self.lits {
522             lit.cut();
523         }
524     }
525 
526     /// Reverses all members in place.
527     pub fn reverse(&mut self) {
528         for lit in &mut self.lits {
529             lit.reverse();
530         }
531     }
532 
533     /// Clears this set of all members.
534     pub fn clear(&mut self) {
535         self.lits.clear();
536     }
537 
538     /// Pops all complete literals out of this set.
539     fn remove_complete(&mut self) -> Vec<Literal> {
540         let mut base = vec![];
541         for lit in mem::replace(&mut self.lits, vec![]) {
542             if lit.is_cut() {
543                 self.lits.push(lit);
544             } else {
545                 base.push(lit);
546             }
547         }
548         base
549     }
550 
551     /// Returns the total number of bytes in this set.
552     fn num_bytes(&self) -> usize {
553         self.lits.iter().fold(0, |accum, lit| accum + lit.len())
554     }
555 
556     /// Returns true if a character class with the given size would cause this
557     /// set to exceed its limits.
558     ///
559     /// The size given should correspond to the number of items in the class.
560     fn class_exceeds_limits(&self, size: usize) -> bool {
561         if size > self.limit_class {
562             return true;
563         }
564         // This is an approximation since codepoints in a char class can encode
565         // to 1-4 bytes.
566         let new_byte_count = if self.lits.is_empty() {
567             size
568         } else {
569             self.lits.iter().fold(0, |accum, lit| {
570                 accum
571                     + if lit.is_cut() {
572                         // If the literal is cut, then we'll never add
573                         // anything to it, so don't count it.
574                         0
575                     } else {
576                         (lit.len() + 1) * size
577                     }
578             })
579         };
580         new_byte_count > self.limit_size
581     }
582 }
583 
584 fn prefixes(expr: &Hir, lits: &mut Literals) {
585     match *expr.kind() {
586         HirKind::Literal(hir::Literal::Unicode(c)) => {
587             let mut buf = [0; 4];
588             lits.cross_add(c.encode_utf8(&mut buf).as_bytes());
589         }
590         HirKind::Literal(hir::Literal::Byte(b)) => {
591             lits.cross_add(&[b]);
592         }
593         HirKind::Class(hir::Class::Unicode(ref cls)) => {
594             if !lits.add_char_class(cls) {
595                 lits.cut();
596             }
597         }
598         HirKind::Class(hir::Class::Bytes(ref cls)) => {
599             if !lits.add_byte_class(cls) {
600                 lits.cut();
601             }
602         }
603         HirKind::Group(hir::Group { ref hir, .. }) => {
604             prefixes(&**hir, lits);
605         }
606         HirKind::Repetition(ref x) => match x.kind {
607             hir::RepetitionKind::ZeroOrOne => {
608                 repeat_zero_or_one_literals(&x.hir, lits, prefixes);
609             }
610             hir::RepetitionKind::ZeroOrMore => {
611                 repeat_zero_or_more_literals(&x.hir, lits, prefixes);
612             }
613             hir::RepetitionKind::OneOrMore => {
614                 repeat_one_or_more_literals(&x.hir, lits, prefixes);
615             }
616             hir::RepetitionKind::Range(ref rng) => {
617                 let (min, max) = match *rng {
618                     hir::RepetitionRange::Exactly(m) => (m, Some(m)),
619                     hir::RepetitionRange::AtLeast(m) => (m, None),
620                     hir::RepetitionRange::Bounded(m, n) => (m, Some(n)),
621                 };
622                 repeat_range_literals(
623                     &x.hir, min, max, x.greedy, lits, prefixes,
624                 )
625             }
626         },
627         HirKind::Concat(ref es) if es.is_empty() => {}
628         HirKind::Concat(ref es) if es.len() == 1 => prefixes(&es[0], lits),
629         HirKind::Concat(ref es) => {
630             for e in es {
631                 if let HirKind::Anchor(hir::Anchor::StartText) = *e.kind() {
632                     if !lits.is_empty() {
633                         lits.cut();
634                         break;
635                     }
636                     lits.add(Literal::empty());
637                     continue;
638                 }
639                 let mut lits2 = lits.to_empty();
640                 prefixes(e, &mut lits2);
641                 if !lits.cross_product(&lits2) || !lits2.any_complete() {
642                     // If this expression couldn't yield any literal that
643                     // could be extended, then we need to quit. Since we're
644                     // short-circuiting, we also need to freeze every member.
645                     lits.cut();
646                     break;
647                 }
648             }
649         }
650         HirKind::Alternation(ref es) => {
651             alternate_literals(es, lits, prefixes);
652         }
653         _ => lits.cut(),
654     }
655 }
656 
657 fn suffixes(expr: &Hir, lits: &mut Literals) {
658     match *expr.kind() {
659         HirKind::Literal(hir::Literal::Unicode(c)) => {
660             let mut buf = [0u8; 4];
661             let i = c.encode_utf8(&mut buf).len();
662             let buf = &mut buf[..i];
663             buf.reverse();
664             lits.cross_add(buf);
665         }
666         HirKind::Literal(hir::Literal::Byte(b)) => {
667             lits.cross_add(&[b]);
668         }
669         HirKind::Class(hir::Class::Unicode(ref cls)) => {
670             if !lits.add_char_class_reverse(cls) {
671                 lits.cut();
672             }
673         }
674         HirKind::Class(hir::Class::Bytes(ref cls)) => {
675             if !lits.add_byte_class(cls) {
676                 lits.cut();
677             }
678         }
679         HirKind::Group(hir::Group { ref hir, .. }) => {
680             suffixes(&**hir, lits);
681         }
682         HirKind::Repetition(ref x) => match x.kind {
683             hir::RepetitionKind::ZeroOrOne => {
684                 repeat_zero_or_one_literals(&x.hir, lits, suffixes);
685             }
686             hir::RepetitionKind::ZeroOrMore => {
687                 repeat_zero_or_more_literals(&x.hir, lits, suffixes);
688             }
689             hir::RepetitionKind::OneOrMore => {
690                 repeat_one_or_more_literals(&x.hir, lits, suffixes);
691             }
692             hir::RepetitionKind::Range(ref rng) => {
693                 let (min, max) = match *rng {
694                     hir::RepetitionRange::Exactly(m) => (m, Some(m)),
695                     hir::RepetitionRange::AtLeast(m) => (m, None),
696                     hir::RepetitionRange::Bounded(m, n) => (m, Some(n)),
697                 };
698                 repeat_range_literals(
699                     &x.hir, min, max, x.greedy, lits, suffixes,
700                 )
701             }
702         },
703         HirKind::Concat(ref es) if es.is_empty() => {}
704         HirKind::Concat(ref es) if es.len() == 1 => suffixes(&es[0], lits),
705         HirKind::Concat(ref es) => {
706             for e in es.iter().rev() {
707                 if let HirKind::Anchor(hir::Anchor::EndText) = *e.kind() {
708                     if !lits.is_empty() {
709                         lits.cut();
710                         break;
711                     }
712                     lits.add(Literal::empty());
713                     continue;
714                 }
715                 let mut lits2 = lits.to_empty();
716                 suffixes(e, &mut lits2);
717                 if !lits.cross_product(&lits2) || !lits2.any_complete() {
718                     // If this expression couldn't yield any literal that
719                     // could be extended, then we need to quit. Since we're
720                     // short-circuiting, we also need to freeze every member.
721                     lits.cut();
722                     break;
723                 }
724             }
725         }
726         HirKind::Alternation(ref es) => {
727             alternate_literals(es, lits, suffixes);
728         }
729         _ => lits.cut(),
730     }
731 }
732 
733 fn repeat_zero_or_one_literals<F: FnMut(&Hir, &mut Literals)>(
734     e: &Hir,
735     lits: &mut Literals,
736     mut f: F,
737 ) {
738     let (mut lits2, mut lits3) = (lits.clone(), lits.to_empty());
739     lits3.set_limit_size(lits.limit_size() / 2);
740     f(e, &mut lits3);
741 
742     if lits3.is_empty() || !lits2.cross_product(&lits3) {
743         lits.cut();
744         return;
745     }
746     lits2.add(Literal::empty());
747     if !lits.union(lits2) {
748         lits.cut();
749     }
750 }
751 
752 fn repeat_zero_or_more_literals<F: FnMut(&Hir, &mut Literals)>(
753     e: &Hir,
754     lits: &mut Literals,
755     mut f: F,
756 ) {
757     let (mut lits2, mut lits3) = (lits.clone(), lits.to_empty());
758     lits3.set_limit_size(lits.limit_size() / 2);
759     f(e, &mut lits3);
760 
761     if lits3.is_empty() || !lits2.cross_product(&lits3) {
762         lits.cut();
763         return;
764     }
765     lits2.cut();
766     lits2.add(Literal::empty());
767     if !lits.union(lits2) {
768         lits.cut();
769     }
770 }
771 
772 fn repeat_one_or_more_literals<F: FnMut(&Hir, &mut Literals)>(
773     e: &Hir,
774     lits: &mut Literals,
775     mut f: F,
776 ) {
777     f(e, lits);
778     lits.cut();
779 }
780 
781 fn repeat_range_literals<F: FnMut(&Hir, &mut Literals)>(
782     e: &Hir,
783     min: u32,
784     max: Option<u32>,
785     greedy: bool,
786     lits: &mut Literals,
787     mut f: F,
788 ) {
789     if min == 0 {
790         // This is a bit conservative. If `max` is set, then we could
791         // treat this as a finite set of alternations. For now, we
792         // just treat it as `e*`.
793         f(
794             &Hir::repetition(hir::Repetition {
795                 kind: hir::RepetitionKind::ZeroOrMore,
796                 greedy: greedy,
797                 hir: Box::new(e.clone()),
798             }),
799             lits,
800         );
801     } else {
802         if min > 0 {
803             let n = cmp::min(lits.limit_size, min as usize);
804             let es = iter::repeat(e.clone()).take(n).collect();
805             f(&Hir::concat(es), lits);
806             if n < min as usize || lits.contains_empty() {
807                 lits.cut();
808             }
809         }
810         if max.map_or(true, |max| min < max) {
811             lits.cut();
812         }
813     }
814 }
815 
816 fn alternate_literals<F: FnMut(&Hir, &mut Literals)>(
817     es: &[Hir],
818     lits: &mut Literals,
819     mut f: F,
820 ) {
821     let mut lits2 = lits.to_empty();
822     for e in es {
823         let mut lits3 = lits.to_empty();
824         lits3.set_limit_size(lits.limit_size() / 5);
825         f(e, &mut lits3);
826         if lits3.is_empty() || !lits2.union(lits3) {
827             // If we couldn't find suffixes for *any* of the
828             // alternates, then the entire alternation has to be thrown
829             // away and any existing members must be frozen. Similarly,
830             // if the union couldn't complete, stop and freeze.
831             lits.cut();
832             return;
833         }
834     }
835     if !lits.cross_product(&lits2) {
836         lits.cut();
837     }
838 }
839 
840 impl fmt::Debug for Literals {
841     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842         f.debug_struct("Literals")
843             .field("lits", &self.lits)
844             .field("limit_size", &self.limit_size)
845             .field("limit_class", &self.limit_class)
846             .finish()
847     }
848 }
849 
850 impl Literal {
851     /// Returns a new complete literal with the bytes given.
852     pub fn new(bytes: Vec<u8>) -> Literal {
853         Literal { v: bytes, cut: false }
854     }
855 
856     /// Returns a new complete empty literal.
857     pub fn empty() -> Literal {
858         Literal { v: vec![], cut: false }
859     }
860 
861     /// Returns true if this literal was "cut."
862     pub fn is_cut(&self) -> bool {
863         self.cut
864     }
865 
866     /// Cuts this literal.
867     pub fn cut(&mut self) {
868         self.cut = true;
869     }
870 }
871 
872 impl PartialEq for Literal {
873     fn eq(&self, other: &Literal) -> bool {
874         self.v == other.v
875     }
876 }
877 
878 impl PartialOrd for Literal {
879     fn partial_cmp(&self, other: &Literal) -> Option<cmp::Ordering> {
880         self.v.partial_cmp(&other.v)
881     }
882 }
883 
884 impl fmt::Debug for Literal {
885     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
886         if self.is_cut() {
887             write!(f, "Cut({})", escape_unicode(&self.v))
888         } else {
889             write!(f, "Complete({})", escape_unicode(&self.v))
890         }
891     }
892 }
893 
894 impl AsRef<[u8]> for Literal {
895     fn as_ref(&self) -> &[u8] {
896         &self.v
897     }
898 }
899 
900 impl ops::Deref for Literal {
901     type Target = Vec<u8>;
902     fn deref(&self) -> &Vec<u8> {
903         &self.v
904     }
905 }
906 
907 impl ops::DerefMut for Literal {
908     fn deref_mut(&mut self) -> &mut Vec<u8> {
909         &mut self.v
910     }
911 }
912 
913 fn position(needle: &[u8], mut haystack: &[u8]) -> Option<usize> {
914     let mut i = 0;
915     while haystack.len() >= needle.len() {
916         if needle == &haystack[..needle.len()] {
917             return Some(i);
918         }
919         i += 1;
920         haystack = &haystack[1..];
921     }
922     None
923 }
924 
925 fn escape_unicode(bytes: &[u8]) -> String {
926     let show = match ::std::str::from_utf8(bytes) {
927         Ok(v) => v.to_string(),
928         Err(_) => escape_bytes(bytes),
929     };
930     let mut space_escaped = String::new();
931     for c in show.chars() {
932         if c.is_whitespace() {
933             let escaped = if c as u32 <= 0x7F {
934                 escape_byte(c as u8)
935             } else {
936                 if c as u32 <= 0xFFFF {
937                     format!(r"\u{{{:04x}}}", c as u32)
938                 } else {
939                     format!(r"\U{{{:08x}}}", c as u32)
940                 }
941             };
942             space_escaped.push_str(&escaped);
943         } else {
944             space_escaped.push(c);
945         }
946     }
947     space_escaped
948 }
949 
950 fn escape_bytes(bytes: &[u8]) -> String {
951     let mut s = String::new();
952     for &b in bytes {
953         s.push_str(&escape_byte(b));
954     }
955     s
956 }
957 
958 fn escape_byte(byte: u8) -> String {
959     use std::ascii::escape_default;
960 
961     let escaped: Vec<u8> = escape_default(byte).collect();
962     String::from_utf8_lossy(&escaped).into_owned()
963 }
964 
965 fn cls_char_count(cls: &hir::ClassUnicode) -> usize {
966     cls.iter().map(|&r| 1 + (r.end as u32) - (r.start as u32)).sum::<u32>()
967         as usize
968 }
969 
970 fn cls_byte_count(cls: &hir::ClassBytes) -> usize {
971     cls.iter().map(|&r| 1 + (r.end as u32) - (r.start as u32)).sum::<u32>()
972         as usize
973 }
974 
975 #[cfg(test)]
976 mod tests {
977     use std::fmt;
978 
979     use super::{escape_bytes, Literal, Literals};
980     use crate::hir::Hir;
981     use crate::ParserBuilder;
982 
983     // To make test failures easier to read.
984     #[derive(Debug, Eq, PartialEq)]
985     struct Bytes(Vec<ULiteral>);
986     #[derive(Debug, Eq, PartialEq)]
987     struct Unicode(Vec<ULiteral>);
988 
989     fn escape_lits(blits: &[Literal]) -> Vec<ULiteral> {
990         let mut ulits = vec![];
991         for blit in blits {
992             ulits
993                 .push(ULiteral { v: escape_bytes(&blit), cut: blit.is_cut() });
994         }
995         ulits
996     }
997 
998     fn create_lits<I: IntoIterator<Item = Literal>>(it: I) -> Literals {
999         Literals {
1000             lits: it.into_iter().collect(),
1001             limit_size: 0,
1002             limit_class: 0,
1003         }
1004     }
1005 
1006     // Needs to be pub for 1.3?
1007     #[derive(Clone, Eq, PartialEq)]
1008     pub struct ULiteral {
1009         v: String,
1010         cut: bool,
1011     }
1012 
1013     impl ULiteral {
1014         fn is_cut(&self) -> bool {
1015             self.cut
1016         }
1017     }
1018 
1019     impl fmt::Debug for ULiteral {
1020         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1021             if self.is_cut() {
1022                 write!(f, "Cut({})", self.v)
1023             } else {
1024                 write!(f, "Complete({})", self.v)
1025             }
1026         }
1027     }
1028 
1029     impl PartialEq<Literal> for ULiteral {
1030         fn eq(&self, other: &Literal) -> bool {
1031             self.v.as_bytes() == &*other.v && self.is_cut() == other.is_cut()
1032         }
1033     }
1034 
1035     impl PartialEq<ULiteral> for Literal {
1036         fn eq(&self, other: &ULiteral) -> bool {
1037             &*self.v == other.v.as_bytes() && self.is_cut() == other.is_cut()
1038         }
1039     }
1040 
1041     #[allow(non_snake_case)]
1042     fn C(s: &'static str) -> ULiteral {
1043         ULiteral { v: s.to_owned(), cut: true }
1044     }
1045     #[allow(non_snake_case)]
1046     fn M(s: &'static str) -> ULiteral {
1047         ULiteral { v: s.to_owned(), cut: false }
1048     }
1049 
1050     fn prefixes(lits: &mut Literals, expr: &Hir) {
1051         lits.union_prefixes(expr);
1052     }
1053 
1054     fn suffixes(lits: &mut Literals, expr: &Hir) {
1055         lits.union_suffixes(expr);
1056     }
1057 
1058     macro_rules! assert_lit_eq {
1059         ($which:ident, $got_lits:expr, $($expected_lit:expr),*) => {{
1060             let expected: Vec<ULiteral> = vec![$($expected_lit),*];
1061             let lits = $got_lits;
1062             assert_eq!(
1063                 $which(expected.clone()),
1064                 $which(escape_lits(lits.literals())));
1065             assert_eq!(
1066                 !expected.is_empty() && expected.iter().all(|l| !l.is_cut()),
1067                 lits.all_complete());
1068             assert_eq!(
1069                 expected.iter().any(|l| !l.is_cut()),
1070                 lits.any_complete());
1071         }};
1072     }
1073 
1074     macro_rules! test_lit {
1075         ($name:ident, $which:ident, $re:expr) => {
1076             test_lit!($name, $which, $re,);
1077         };
1078         ($name:ident, $which:ident, $re:expr, $($lit:expr),*) => {
1079             #[test]
1080             fn $name() {
1081                 let expr = ParserBuilder::new()
1082                     .build()
1083                     .parse($re)
1084                     .unwrap();
1085                 let lits = Literals::$which(&expr);
1086                 assert_lit_eq!(Unicode, lits, $($lit),*);
1087 
1088                 let expr = ParserBuilder::new()
1089                     .allow_invalid_utf8(true)
1090                     .unicode(false)
1091                     .build()
1092                     .parse($re)
1093                     .unwrap();
1094                 let lits = Literals::$which(&expr);
1095                 assert_lit_eq!(Bytes, lits, $($lit),*);
1096             }
1097         };
1098     }
1099 
1100     // ************************************************************************
1101     // Tests for prefix literal extraction.
1102     // ************************************************************************
1103 
1104     // Elementary tests.
1105     test_lit!(pfx_one_lit1, prefixes, "a", M("a"));
1106     test_lit!(pfx_one_lit2, prefixes, "abc", M("abc"));
1107     test_lit!(pfx_one_lit3, prefixes, "(?u)☃", M("\\xe2\\x98\\x83"));
1108     #[cfg(feature = "unicode-case")]
1109     test_lit!(pfx_one_lit4, prefixes, "(?ui)☃", M("\\xe2\\x98\\x83"));
1110     test_lit!(pfx_class1, prefixes, "[1-4]", M("1"), M("2"), M("3"), M("4"));
1111     test_lit!(
1112         pfx_class2,
1113         prefixes,
1114         "(?u)[☃Ⅰ]",
1115         M("\\xe2\\x85\\xa0"),
1116         M("\\xe2\\x98\\x83")
1117     );
1118     #[cfg(feature = "unicode-case")]
1119     test_lit!(
1120         pfx_class3,
1121         prefixes,
1122         "(?ui)[☃Ⅰ]",
1123         M("\\xe2\\x85\\xa0"),
1124         M("\\xe2\\x85\\xb0"),
1125         M("\\xe2\\x98\\x83")
1126     );
1127     test_lit!(pfx_one_lit_casei1, prefixes, "(?i-u)a", M("A"), M("a"));
1128     test_lit!(
1129         pfx_one_lit_casei2,
1130         prefixes,
1131         "(?i-u)abc",
1132         M("ABC"),
1133         M("aBC"),
1134         M("AbC"),
1135         M("abC"),
1136         M("ABc"),
1137         M("aBc"),
1138         M("Abc"),
1139         M("abc")
1140     );
1141     test_lit!(pfx_group1, prefixes, "(a)", M("a"));
1142     test_lit!(pfx_rep_zero_or_one1, prefixes, "a?");
1143     test_lit!(pfx_rep_zero_or_one2, prefixes, "(?:abc)?");
1144     test_lit!(pfx_rep_zero_or_more1, prefixes, "a*");
1145     test_lit!(pfx_rep_zero_or_more2, prefixes, "(?:abc)*");
1146     test_lit!(pfx_rep_one_or_more1, prefixes, "a+", C("a"));
1147     test_lit!(pfx_rep_one_or_more2, prefixes, "(?:abc)+", C("abc"));
1148     test_lit!(pfx_rep_nested_one_or_more, prefixes, "(?:a+)+", C("a"));
1149     test_lit!(pfx_rep_range1, prefixes, "a{0}");
1150     test_lit!(pfx_rep_range2, prefixes, "a{0,}");
1151     test_lit!(pfx_rep_range3, prefixes, "a{0,1}");
1152     test_lit!(pfx_rep_range4, prefixes, "a{1}", M("a"));
1153     test_lit!(pfx_rep_range5, prefixes, "a{2}", M("aa"));
1154     test_lit!(pfx_rep_range6, prefixes, "a{1,2}", C("a"));
1155     test_lit!(pfx_rep_range7, prefixes, "a{2,3}", C("aa"));
1156 
1157     // Test regexes with concatenations.
1158     test_lit!(pfx_cat1, prefixes, "(?:a)(?:b)", M("ab"));
1159     test_lit!(pfx_cat2, prefixes, "[ab]z", M("az"), M("bz"));
1160     test_lit!(
1161         pfx_cat3,
1162         prefixes,
1163         "(?i-u)[ab]z",
1164         M("AZ"),
1165         M("BZ"),
1166         M("aZ"),
1167         M("bZ"),
1168         M("Az"),
1169         M("Bz"),
1170         M("az"),
1171         M("bz")
1172     );
1173     test_lit!(
1174         pfx_cat4,
1175         prefixes,
1176         "[ab][yz]",
1177         M("ay"),
1178         M("by"),
1179         M("az"),
1180         M("bz")
1181     );
1182     test_lit!(pfx_cat5, prefixes, "a*b", C("a"), M("b"));
1183     test_lit!(pfx_cat6, prefixes, "a*b*c", C("a"), C("b"), M("c"));
1184     test_lit!(pfx_cat7, prefixes, "a*b*c+", C("a"), C("b"), C("c"));
1185     test_lit!(pfx_cat8, prefixes, "a*b+c", C("a"), C("b"));
1186     test_lit!(pfx_cat9, prefixes, "a*b+c*", C("a"), C("b"));
1187     test_lit!(pfx_cat10, prefixes, "ab*", C("ab"), M("a"));
1188     test_lit!(pfx_cat11, prefixes, "ab*c", C("ab"), M("ac"));
1189     test_lit!(pfx_cat12, prefixes, "ab+", C("ab"));
1190     test_lit!(pfx_cat13, prefixes, "ab+c", C("ab"));
1191     test_lit!(pfx_cat14, prefixes, "a^", C("a"));
1192     test_lit!(pfx_cat15, prefixes, "$a");
1193     test_lit!(pfx_cat16, prefixes, r"ab*c", C("ab"), M("ac"));
1194     test_lit!(pfx_cat17, prefixes, r"ab+c", C("ab"));
1195     test_lit!(pfx_cat18, prefixes, r"z*azb", C("z"), M("azb"));
1196     test_lit!(pfx_cat19, prefixes, "a.z", C("a"));
1197 
1198     // Test regexes with alternations.
1199     test_lit!(pfx_alt1, prefixes, "a|b", M("a"), M("b"));
1200     test_lit!(pfx_alt2, prefixes, "[1-3]|b", M("1"), M("2"), M("3"), M("b"));
1201     test_lit!(pfx_alt3, prefixes, "y(?:a|b)z", M("yaz"), M("ybz"));
1202     test_lit!(pfx_alt4, prefixes, "a|b*");
1203     test_lit!(pfx_alt5, prefixes, "a|b+", M("a"), C("b"));
1204     test_lit!(pfx_alt6, prefixes, "a|(?:b|c*)");
1205     test_lit!(
1206         pfx_alt7,
1207         prefixes,
1208         "(a|b)*c|(a|ab)*c",
1209         C("a"),
1210         C("b"),
1211         M("c"),
1212         C("a"),
1213         C("ab"),
1214         M("c")
1215     );
1216     test_lit!(pfx_alt8, prefixes, "a*b|c", C("a"), M("b"), M("c"));
1217 
1218     // Test regexes with empty assertions.
1219     test_lit!(pfx_empty1, prefixes, "^a", M("a"));
1220     test_lit!(pfx_empty2, prefixes, "a${2}", C("a"));
1221     test_lit!(pfx_empty3, prefixes, "^abc", M("abc"));
1222     test_lit!(pfx_empty4, prefixes, "(?:^abc)|(?:^z)", M("abc"), M("z"));
1223 
1224     // Make sure some curious regexes have no prefixes.
1225     test_lit!(pfx_nothing1, prefixes, ".");
1226     test_lit!(pfx_nothing2, prefixes, "(?s).");
1227     test_lit!(pfx_nothing3, prefixes, "^");
1228     test_lit!(pfx_nothing4, prefixes, "$");
1229     test_lit!(pfx_nothing6, prefixes, "(?m)$");
1230     test_lit!(pfx_nothing7, prefixes, r"\b");
1231     test_lit!(pfx_nothing8, prefixes, r"\B");
1232 
1233     // Test a few regexes that defeat any prefix literal detection.
1234     test_lit!(pfx_defeated1, prefixes, ".a");
1235     test_lit!(pfx_defeated2, prefixes, "(?s).a");
1236     test_lit!(pfx_defeated3, prefixes, "a*b*c*");
1237     test_lit!(pfx_defeated4, prefixes, "a|.");
1238     test_lit!(pfx_defeated5, prefixes, ".|a");
1239     test_lit!(pfx_defeated6, prefixes, "a|^");
1240     test_lit!(pfx_defeated7, prefixes, ".(?:a(?:b)(?:c))");
1241     test_lit!(pfx_defeated8, prefixes, "$a");
1242     test_lit!(pfx_defeated9, prefixes, "(?m)$a");
1243     test_lit!(pfx_defeated10, prefixes, r"\ba");
1244     test_lit!(pfx_defeated11, prefixes, r"\Ba");
1245     test_lit!(pfx_defeated12, prefixes, "^*a");
1246     test_lit!(pfx_defeated13, prefixes, "^+a");
1247 
1248     test_lit!(
1249         pfx_crazy1,
1250         prefixes,
1251         r"M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]",
1252         C("Mo\\'am"),
1253         C("Mu\\'am"),
1254         C("Moam"),
1255         C("Muam")
1256     );
1257 
1258     // ************************************************************************
1259     // Tests for quiting prefix literal search.
1260     // ************************************************************************
1261 
1262     macro_rules! test_exhausted {
1263         ($name:ident, $which:ident, $re:expr) => {
1264             test_exhausted!($name, $which, $re,);
1265         };
1266         ($name:ident, $which:ident, $re:expr, $($lit:expr),*) => {
1267             #[test]
1268             fn $name() {
1269                 let expr = ParserBuilder::new()
1270                     .build()
1271                     .parse($re)
1272                     .unwrap();
1273                 let mut lits = Literals::empty();
1274                 lits.set_limit_size(20).set_limit_class(10);
1275                 $which(&mut lits, &expr);
1276                 assert_lit_eq!(Unicode, lits, $($lit),*);
1277 
1278                 let expr = ParserBuilder::new()
1279                     .allow_invalid_utf8(true)
1280                     .unicode(false)
1281                     .build()
1282                     .parse($re)
1283                     .unwrap();
1284                 let mut lits = Literals::empty();
1285                 lits.set_limit_size(20).set_limit_class(10);
1286                 $which(&mut lits, &expr);
1287                 assert_lit_eq!(Bytes, lits, $($lit),*);
1288             }
1289         };
1290     }
1291 
1292     // These test use a much lower limit than the default so that we can
1293     // write test cases of reasonable size.
1294     test_exhausted!(pfx_exhausted1, prefixes, "[a-z]");
1295     test_exhausted!(pfx_exhausted2, prefixes, "[a-z]*A");
1296     test_exhausted!(pfx_exhausted3, prefixes, "A[a-z]Z", C("A"));
1297     test_exhausted!(
1298         pfx_exhausted4,
1299         prefixes,
1300         "(?i-u)foobar",
1301         C("FO"),
1302         C("fO"),
1303         C("Fo"),
1304         C("fo")
1305     );
1306     test_exhausted!(
1307         pfx_exhausted5,
1308         prefixes,
1309         "(?:ab){100}",
1310         C("abababababababababab")
1311     );
1312     test_exhausted!(
1313         pfx_exhausted6,
1314         prefixes,
1315         "(?:(?:ab){100})*cd",
1316         C("ababababab"),
1317         M("cd")
1318     );
1319     test_exhausted!(
1320         pfx_exhausted7,
1321         prefixes,
1322         "z(?:(?:ab){100})*cd",
1323         C("zababababab"),
1324         M("zcd")
1325     );
1326     test_exhausted!(
1327         pfx_exhausted8,
1328         prefixes,
1329         "aaaaaaaaaaaaaaaaaaaaz",
1330         C("aaaaaaaaaaaaaaaaaaaa")
1331     );
1332 
1333     // ************************************************************************
1334     // Tests for suffix literal extraction.
1335     // ************************************************************************
1336 
1337     // Elementary tests.
1338     test_lit!(sfx_one_lit1, suffixes, "a", M("a"));
1339     test_lit!(sfx_one_lit2, suffixes, "abc", M("abc"));
1340     test_lit!(sfx_one_lit3, suffixes, "(?u)☃", M("\\xe2\\x98\\x83"));
1341     #[cfg(feature = "unicode-case")]
1342     test_lit!(sfx_one_lit4, suffixes, "(?ui)☃", M("\\xe2\\x98\\x83"));
1343     test_lit!(sfx_class1, suffixes, "[1-4]", M("1"), M("2"), M("3"), M("4"));
1344     test_lit!(
1345         sfx_class2,
1346         suffixes,
1347         "(?u)[☃Ⅰ]",
1348         M("\\xe2\\x85\\xa0"),
1349         M("\\xe2\\x98\\x83")
1350     );
1351     #[cfg(feature = "unicode-case")]
1352     test_lit!(
1353         sfx_class3,
1354         suffixes,
1355         "(?ui)[☃Ⅰ]",
1356         M("\\xe2\\x85\\xa0"),
1357         M("\\xe2\\x85\\xb0"),
1358         M("\\xe2\\x98\\x83")
1359     );
1360     test_lit!(sfx_one_lit_casei1, suffixes, "(?i-u)a", M("A"), M("a"));
1361     test_lit!(
1362         sfx_one_lit_casei2,
1363         suffixes,
1364         "(?i-u)abc",
1365         M("ABC"),
1366         M("ABc"),
1367         M("AbC"),
1368         M("Abc"),
1369         M("aBC"),
1370         M("aBc"),
1371         M("abC"),
1372         M("abc")
1373     );
1374     test_lit!(sfx_group1, suffixes, "(a)", M("a"));
1375     test_lit!(sfx_rep_zero_or_one1, suffixes, "a?");
1376     test_lit!(sfx_rep_zero_or_one2, suffixes, "(?:abc)?");
1377     test_lit!(sfx_rep_zero_or_more1, suffixes, "a*");
1378     test_lit!(sfx_rep_zero_or_more2, suffixes, "(?:abc)*");
1379     test_lit!(sfx_rep_one_or_more1, suffixes, "a+", C("a"));
1380     test_lit!(sfx_rep_one_or_more2, suffixes, "(?:abc)+", C("abc"));
1381     test_lit!(sfx_rep_nested_one_or_more, suffixes, "(?:a+)+", C("a"));
1382     test_lit!(sfx_rep_range1, suffixes, "a{0}");
1383     test_lit!(sfx_rep_range2, suffixes, "a{0,}");
1384     test_lit!(sfx_rep_range3, suffixes, "a{0,1}");
1385     test_lit!(sfx_rep_range4, suffixes, "a{1}", M("a"));
1386     test_lit!(sfx_rep_range5, suffixes, "a{2}", M("aa"));
1387     test_lit!(sfx_rep_range6, suffixes, "a{1,2}", C("a"));
1388     test_lit!(sfx_rep_range7, suffixes, "a{2,3}", C("aa"));
1389 
1390     // Test regexes with concatenations.
1391     test_lit!(sfx_cat1, suffixes, "(?:a)(?:b)", M("ab"));
1392     test_lit!(sfx_cat2, suffixes, "[ab]z", M("az"), M("bz"));
1393     test_lit!(
1394         sfx_cat3,
1395         suffixes,
1396         "(?i-u)[ab]z",
1397         M("AZ"),
1398         M("Az"),
1399         M("BZ"),
1400         M("Bz"),
1401         M("aZ"),
1402         M("az"),
1403         M("bZ"),
1404         M("bz")
1405     );
1406     test_lit!(
1407         sfx_cat4,
1408         suffixes,
1409         "[ab][yz]",
1410         M("ay"),
1411         M("az"),
1412         M("by"),
1413         M("bz")
1414     );
1415     test_lit!(sfx_cat5, suffixes, "a*b", C("ab"), M("b"));
1416     test_lit!(sfx_cat6, suffixes, "a*b*c", C("bc"), C("ac"), M("c"));
1417     test_lit!(sfx_cat7, suffixes, "a*b*c+", C("c"));
1418     test_lit!(sfx_cat8, suffixes, "a*b+c", C("bc"));
1419     test_lit!(sfx_cat9, suffixes, "a*b+c*", C("c"), C("b"));
1420     test_lit!(sfx_cat10, suffixes, "ab*", C("b"), M("a"));
1421     test_lit!(sfx_cat11, suffixes, "ab*c", C("bc"), M("ac"));
1422     test_lit!(sfx_cat12, suffixes, "ab+", C("b"));
1423     test_lit!(sfx_cat13, suffixes, "ab+c", C("bc"));
1424     test_lit!(sfx_cat14, suffixes, "a^");
1425     test_lit!(sfx_cat15, suffixes, "$a", C("a"));
1426     test_lit!(sfx_cat16, suffixes, r"ab*c", C("bc"), M("ac"));
1427     test_lit!(sfx_cat17, suffixes, r"ab+c", C("bc"));
1428     test_lit!(sfx_cat18, suffixes, r"z*azb", C("zazb"), M("azb"));
1429     test_lit!(sfx_cat19, suffixes, "a.z", C("z"));
1430 
1431     // Test regexes with alternations.
1432     test_lit!(sfx_alt1, suffixes, "a|b", M("a"), M("b"));
1433     test_lit!(sfx_alt2, suffixes, "[1-3]|b", M("1"), M("2"), M("3"), M("b"));
1434     test_lit!(sfx_alt3, suffixes, "y(?:a|b)z", M("yaz"), M("ybz"));
1435     test_lit!(sfx_alt4, suffixes, "a|b*");
1436     test_lit!(sfx_alt5, suffixes, "a|b+", M("a"), C("b"));
1437     test_lit!(sfx_alt6, suffixes, "a|(?:b|c*)");
1438     test_lit!(
1439         sfx_alt7,
1440         suffixes,
1441         "(a|b)*c|(a|ab)*c",
1442         C("ac"),
1443         C("bc"),
1444         M("c"),
1445         C("ac"),
1446         C("abc"),
1447         M("c")
1448     );
1449     test_lit!(sfx_alt8, suffixes, "a*b|c", C("ab"), M("b"), M("c"));
1450 
1451     // Test regexes with empty assertions.
1452     test_lit!(sfx_empty1, suffixes, "a$", M("a"));
1453     test_lit!(sfx_empty2, suffixes, "${2}a", C("a"));
1454 
1455     // Make sure some curious regexes have no suffixes.
1456     test_lit!(sfx_nothing1, suffixes, ".");
1457     test_lit!(sfx_nothing2, suffixes, "(?s).");
1458     test_lit!(sfx_nothing3, suffixes, "^");
1459     test_lit!(sfx_nothing4, suffixes, "$");
1460     test_lit!(sfx_nothing6, suffixes, "(?m)$");
1461     test_lit!(sfx_nothing7, suffixes, r"\b");
1462     test_lit!(sfx_nothing8, suffixes, r"\B");
1463 
1464     // Test a few regexes that defeat any suffix literal detection.
1465     test_lit!(sfx_defeated1, suffixes, "a.");
1466     test_lit!(sfx_defeated2, suffixes, "(?s)a.");
1467     test_lit!(sfx_defeated3, suffixes, "a*b*c*");
1468     test_lit!(sfx_defeated4, suffixes, "a|.");
1469     test_lit!(sfx_defeated5, suffixes, ".|a");
1470     test_lit!(sfx_defeated6, suffixes, "a|^");
1471     test_lit!(sfx_defeated7, suffixes, "(?:a(?:b)(?:c)).");
1472     test_lit!(sfx_defeated8, suffixes, "a^");
1473     test_lit!(sfx_defeated9, suffixes, "(?m)a$");
1474     test_lit!(sfx_defeated10, suffixes, r"a\b");
1475     test_lit!(sfx_defeated11, suffixes, r"a\B");
1476     test_lit!(sfx_defeated12, suffixes, "a^*");
1477     test_lit!(sfx_defeated13, suffixes, "a^+");
1478 
1479     // These test use a much lower limit than the default so that we can
1480     // write test cases of reasonable size.
1481     test_exhausted!(sfx_exhausted1, suffixes, "[a-z]");
1482     test_exhausted!(sfx_exhausted2, suffixes, "A[a-z]*");
1483     test_exhausted!(sfx_exhausted3, suffixes, "A[a-z]Z", C("Z"));
1484     test_exhausted!(
1485         sfx_exhausted4,
1486         suffixes,
1487         "(?i-u)foobar",
1488         C("AR"),
1489         C("Ar"),
1490         C("aR"),
1491         C("ar")
1492     );
1493     test_exhausted!(
1494         sfx_exhausted5,
1495         suffixes,
1496         "(?:ab){100}",
1497         C("abababababababababab")
1498     );
1499     test_exhausted!(
1500         sfx_exhausted6,
1501         suffixes,
1502         "cd(?:(?:ab){100})*",
1503         C("ababababab"),
1504         M("cd")
1505     );
1506     test_exhausted!(
1507         sfx_exhausted7,
1508         suffixes,
1509         "cd(?:(?:ab){100})*z",
1510         C("abababababz"),
1511         M("cdz")
1512     );
1513     test_exhausted!(
1514         sfx_exhausted8,
1515         suffixes,
1516         "zaaaaaaaaaaaaaaaaaaaa",
1517         C("aaaaaaaaaaaaaaaaaaaa")
1518     );
1519 
1520     // ************************************************************************
1521     // Tests for generating unambiguous literal sets.
1522     // ************************************************************************
1523 
1524     macro_rules! test_unamb {
1525         ($name:ident, $given:expr, $expected:expr) => {
1526             #[test]
1527             fn $name() {
1528                 let given: Vec<Literal> = $given
1529                     .into_iter()
1530                     .map(|ul| {
1531                         let cut = ul.is_cut();
1532                         Literal { v: ul.v.into_bytes(), cut: cut }
1533                     })
1534                     .collect();
1535                 let lits = create_lits(given);
1536                 let got = lits.unambiguous_prefixes();
1537                 assert_eq!($expected, escape_lits(got.literals()));
1538             }
1539         };
1540     }
1541 
1542     test_unamb!(unambiguous1, vec![M("z"), M("azb")], vec![C("a"), C("z")]);
1543     test_unamb!(
1544         unambiguous2,
1545         vec![M("zaaaaaa"), M("aa")],
1546         vec![C("aa"), C("z")]
1547     );
1548     test_unamb!(
1549         unambiguous3,
1550         vec![M("Sherlock"), M("Watson")],
1551         vec![M("Sherlock"), M("Watson")]
1552     );
1553     test_unamb!(unambiguous4, vec![M("abc"), M("bc")], vec![C("a"), C("bc")]);
1554     test_unamb!(unambiguous5, vec![M("bc"), M("abc")], vec![C("a"), C("bc")]);
1555     test_unamb!(unambiguous6, vec![M("a"), M("aa")], vec![C("a")]);
1556     test_unamb!(unambiguous7, vec![M("aa"), M("a")], vec![C("a")]);
1557     test_unamb!(unambiguous8, vec![M("ab"), M("a")], vec![C("a")]);
1558     test_unamb!(
1559         unambiguous9,
1560         vec![M("ac"), M("bc"), M("c"), M("ac"), M("abc"), M("c")],
1561         vec![C("a"), C("b"), C("c")]
1562     );
1563     test_unamb!(
1564         unambiguous10,
1565         vec![M("Mo'"), M("Mu'"), M("Mo"), M("Mu")],
1566         vec![C("Mo"), C("Mu")]
1567     );
1568     test_unamb!(
1569         unambiguous11,
1570         vec![M("zazb"), M("azb")],
1571         vec![C("a"), C("z")]
1572     );
1573     test_unamb!(unambiguous12, vec![M("foo"), C("foo")], vec![C("foo")]);
1574     test_unamb!(
1575         unambiguous13,
1576         vec![M("ABCX"), M("CDAX"), M("BCX")],
1577         vec![C("A"), C("BCX"), C("CD")]
1578     );
1579     test_unamb!(
1580         unambiguous14,
1581         vec![M("IMGX"), M("MVIX"), M("MGX"), M("DSX")],
1582         vec![M("DSX"), C("I"), C("MGX"), C("MV")]
1583     );
1584     test_unamb!(
1585         unambiguous15,
1586         vec![M("IMG_"), M("MG_"), M("CIMG")],
1587         vec![C("C"), C("I"), C("MG_")]
1588     );
1589 
1590     // ************************************************************************
1591     // Tests for suffix trimming.
1592     // ************************************************************************
1593     macro_rules! test_trim {
1594         ($name:ident, $trim:expr, $given:expr, $expected:expr) => {
1595             #[test]
1596             fn $name() {
1597                 let given: Vec<Literal> = $given
1598                     .into_iter()
1599                     .map(|ul| {
1600                         let cut = ul.is_cut();
1601                         Literal { v: ul.v.into_bytes(), cut: cut }
1602                     })
1603                     .collect();
1604                 let lits = create_lits(given);
1605                 let got = lits.trim_suffix($trim).unwrap();
1606                 assert_eq!($expected, escape_lits(got.literals()));
1607             }
1608         };
1609     }
1610 
1611     test_trim!(trim1, 1, vec![M("ab"), M("yz")], vec![C("a"), C("y")]);
1612     test_trim!(trim2, 1, vec![M("abc"), M("abd")], vec![C("ab")]);
1613     test_trim!(trim3, 2, vec![M("abc"), M("abd")], vec![C("a")]);
1614     test_trim!(trim4, 2, vec![M("abc"), M("ghij")], vec![C("a"), C("gh")]);
1615 
1616     // ************************************************************************
1617     // Tests for longest common prefix.
1618     // ************************************************************************
1619 
1620     macro_rules! test_lcp {
1621         ($name:ident, $given:expr, $expected:expr) => {
1622             #[test]
1623             fn $name() {
1624                 let given: Vec<Literal> = $given
1625                     .into_iter()
1626                     .map(|s: &str| Literal {
1627                         v: s.to_owned().into_bytes(),
1628                         cut: false,
1629                     })
1630                     .collect();
1631                 let lits = create_lits(given);
1632                 let got = lits.longest_common_prefix();
1633                 assert_eq!($expected, escape_bytes(got));
1634             }
1635         };
1636     }
1637 
1638     test_lcp!(lcp1, vec!["a"], "a");
1639     test_lcp!(lcp2, vec![], "");
1640     test_lcp!(lcp3, vec!["a", "b"], "");
1641     test_lcp!(lcp4, vec!["ab", "ab"], "ab");
1642     test_lcp!(lcp5, vec!["ab", "a"], "a");
1643     test_lcp!(lcp6, vec!["a", "ab"], "a");
1644     test_lcp!(lcp7, vec!["ab", "b"], "");
1645     test_lcp!(lcp8, vec!["b", "ab"], "");
1646     test_lcp!(lcp9, vec!["foobar", "foobaz"], "fooba");
1647     test_lcp!(lcp10, vec!["foobar", "foobaz", "a"], "");
1648     test_lcp!(lcp11, vec!["a", "foobar", "foobaz"], "");
1649     test_lcp!(lcp12, vec!["foo", "flub", "flab", "floo"], "f");
1650 
1651     // ************************************************************************
1652     // Tests for longest common suffix.
1653     // ************************************************************************
1654 
1655     macro_rules! test_lcs {
1656         ($name:ident, $given:expr, $expected:expr) => {
1657             #[test]
1658             fn $name() {
1659                 let given: Vec<Literal> = $given
1660                     .into_iter()
1661                     .map(|s: &str| Literal {
1662                         v: s.to_owned().into_bytes(),
1663                         cut: false,
1664                     })
1665                     .collect();
1666                 let lits = create_lits(given);
1667                 let got = lits.longest_common_suffix();
1668                 assert_eq!($expected, escape_bytes(got));
1669             }
1670         };
1671     }
1672 
1673     test_lcs!(lcs1, vec!["a"], "a");
1674     test_lcs!(lcs2, vec![], "");
1675     test_lcs!(lcs3, vec!["a", "b"], "");
1676     test_lcs!(lcs4, vec!["ab", "ab"], "ab");
1677     test_lcs!(lcs5, vec!["ab", "a"], "");
1678     test_lcs!(lcs6, vec!["a", "ab"], "");
1679     test_lcs!(lcs7, vec!["ab", "b"], "b");
1680     test_lcs!(lcs8, vec!["b", "ab"], "b");
1681     test_lcs!(lcs9, vec!["barfoo", "bazfoo"], "foo");
1682     test_lcs!(lcs10, vec!["barfoo", "bazfoo", "a"], "");
1683     test_lcs!(lcs11, vec!["a", "barfoo", "bazfoo"], "");
1684     test_lcs!(lcs12, vec!["flub", "bub", "boob", "dub"], "b");
1685 }
1686