Skip to main content

yo_common/
re.rs

1//! A POSIX extended regular expression matcher over bytes.
2//!
3//! Redis has one command that takes a regular expression, `ARGREP ... RE`, and
4//! it gets it from TRE, which it vendors under `deps/tre`. What it asks TRE for
5//! is narrow: `REG_EXTENDED | REG_NOSUB | REG_USEBYTES`, optionally `REG_ICASE`,
6//! and then a yes or no per element. No capture groups are read, no match
7//! offsets are read, and a pattern with a backreference in it is refused before
8//! it is ever run. So the thing that has to be built is a boolean matcher for
9//! extended regular expressions over bytes, which is a much smaller object than
10//! a general purpose regex crate.
11//!
12//! That is the whole reason this is here rather than a dependency. The
13//! workspace has four third party crates in it and two of them are only for
14//! tests, and adding a regex engine and its three transitive crates to the
15//! engine that the C ABI and every language binding link against is a large
16//! thing to pay for one command. Writing the narrow version is a few hundred
17//! lines and it comes out with a property the general one cannot promise: the
18//! simulation is a Thompson construction walked with a set of live states, so
19//! matching is linear in the subject and cannot be made to blow up by a pattern.
20//! `ARGREP` runs its predicates over every element a range touches, from a
21//! pattern a client sent, so that is worth having rather than being clever.
22//!
23//! The syntax is TRE's, read off `deps/tre/lib/tre-parse.c` rather than off
24//! POSIX, because the point is to agree with the server people are migrating
25//! from. TRE has a table of macros that run before anything else, so `\n` is a
26//! newline, `\d` is `[[:digit:]]` and `\w` is `[[:alnum:]_]`, and after that a
27//! switch with `\b`, `\B`, `\<`, `\>` and `\xNN`. The one that surprises people
28//! is that a backslash inside a bracket expression is a literal backslash and
29//! not an escape, so `[\d]` is a backslash or a d.
30//!
31//! Bytes rather than characters, the same as `glob`, and for the same reason: an
32//! array element is arbitrary bytes and deciding what a character is would mean
33//! deciding what encoding it is in.
34//!
35//! Every rule in here was either read off a line of TRE or measured against it.
36//! The measuring was done by building TRE from `deps/tre` into a small program
37//! that answers the same question this does, and then generating patterns from
38//! the pieces TRE's parser has cases for and comparing the two answers. That is
39//! how the macro table was found, along with the way a repeated assertion stays
40//! mandatory, the split between the two errors a bad bound gives, and the
41//! handful of places where TRE and Redis's own fast path disagree with each
42//! other. Roughly a quarter of a million comparisons agree.
43
44use core::fmt;
45
46/// The largest `{n,m}` repetition, which is TRE's `RE_DUP_MAX`.
47pub const DUP_MAX: u32 = 255;
48
49/// The largest program a pattern may compile to.
50///
51/// A bound repetition is expanded by copying, so `(a{255}){255}` is sixty five
52/// thousand instructions and nesting one more level is sixteen million. The cap
53/// is what stops a short pattern from turning into a long compile, and it is
54/// generous enough that nothing anyone writes by hand reaches it.
55const PROG_MAX: usize = 100_000;
56
57/// The deepest a pattern may nest groups.
58///
59/// The parser is recursive, so this is the difference between refusing a
60/// pattern and overflowing the stack on the shard thread.
61const DEPTH_MAX: u32 = 64;
62
63/// Why a pattern would not compile.
64///
65/// The names and the messages are TRE's, from `deps/tre/lib/regerror.c`,
66/// because Redis puts the message straight into its error reply and a client
67/// that matches on the text should not be able to tell the two servers apart.
68#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub enum Error {
70    /// `REG_BADPAT`, a pattern that is not one.
71    BadPattern,
72    /// `REG_ECOLLATE`, a `[.` or `[=` bracket item.
73    Collate,
74    /// `REG_ECTYPE`, a `[:name:]` that is not a class.
75    CharClass,
76    /// `REG_EESCAPE`, a backslash at the very end.
77    TrailingBackslash,
78    /// `REG_ESUBREG`, a backreference to a group the pattern does not have.
79    BackRef,
80    /// A backreference to a group that does exist.
81    ///
82    /// Not one of TRE's codes. TRE compiles this and Redis refuses it a step
83    /// later with a sentence of its own, so the message here is that sentence
84    /// and a caller reporting it should not put "invalid regular expression"
85    /// in front of it the way it would for the rest of these.
86    Unsupported,
87    /// `REG_EBRACK`, a bracket expression with no `]`.
88    MissingBracket,
89    /// `REG_EPAREN`, a group with no `)`.
90    MissingParen,
91    /// `REG_EBRACE`, a `\x{` or a `{` with no `}`.
92    MissingBrace,
93    /// `REG_BADBR`, a `{}` whose contents are not a bound.
94    BadBrace,
95    /// `REG_ERANGE`, a bracket range that runs backwards.
96    BadRange,
97    /// `REG_ESPACE`, a pattern that compiles to more than this engine will hold.
98    Space,
99    /// `REG_BADRPT`, a repetition operator with nothing in front of it.
100    BadRepeat,
101    /// `REG_BADMAX`, a `{n,m}` past [`DUP_MAX`].
102    BadMax,
103}
104
105impl Error {
106    /// TRE's message for this code, which is what the client sees.
107    #[must_use]
108    pub const fn as_str(self) -> &'static str {
109        match self {
110            Error::BadPattern => "Invalid regexp",
111            Error::Collate => "Unknown collating element",
112            Error::CharClass => "Unknown character class name",
113            Error::TrailingBackslash => "Trailing backslash",
114            Error::BackRef => "Invalid back reference",
115            Error::Unsupported => "regular expression backreferences are not supported",
116            Error::MissingBracket => "Missing ']'",
117            Error::MissingParen => "Missing ')'",
118            Error::MissingBrace => "Missing '}'",
119            Error::BadBrace => "Invalid contents of {}",
120            Error::BadRange => "Invalid character range",
121            Error::Space => "Out of memory",
122            Error::BadRepeat => "Invalid use of repetition operators",
123            Error::BadMax => "Maximum repetition in {} larger than 255",
124        }
125    }
126}
127
128impl fmt::Display for Error {
129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130        f.write_str(self.as_str())
131    }
132}
133
134/// A set of bytes, as one bit each.
135///
136/// Every consuming step in the program is one of these, so a literal, a `.`, a
137/// bracket expression and a `[:alpha:]` are all the same instruction and the
138/// matcher has one case rather than four.
139#[derive(Clone, Copy, PartialEq, Eq, Debug)]
140struct Class([u64; 4]);
141
142impl Class {
143    const fn empty() -> Class {
144        Class([0; 4])
145    }
146
147    const fn all() -> Class {
148        Class([u64::MAX; 4])
149    }
150
151    fn set(&mut self, b: u8) {
152        self.0[(b >> 6) as usize] |= 1 << (b & 63);
153    }
154
155    fn clear(&mut self, b: u8) {
156        self.0[(b >> 6) as usize] &= !(1 << (b & 63));
157    }
158
159    fn set_range(&mut self, lo: u8, hi: u8) {
160        for b in lo..=hi {
161            self.set(b);
162        }
163    }
164
165    const fn has(self, b: u8) -> bool {
166        self.0[(b >> 6) as usize] >> (b & 63) & 1 == 1
167    }
168
169    fn negate(&mut self) {
170        for w in &mut self.0 {
171            *w = !*w;
172        }
173    }
174
175    /// Add the other case of every letter already in the set.
176    ///
177    /// Done once when the class is built rather than per byte at match time,
178    /// and done to the positive set before a `[^...]` is negated, so `[^a]`
179    /// under NOCASE refuses `A` as well.
180    fn fold_case(&mut self) {
181        for b in b'a'..=b'z' {
182            if self.has(b) {
183                self.set(b - 32);
184            }
185        }
186        for b in b'A'..=b'Z' {
187            if self.has(b) {
188                self.set(b + 32);
189            }
190        }
191    }
192}
193
194/// A zero width test, which the closure evaluates rather than the step.
195#[derive(Clone, Copy, PartialEq, Eq, Debug)]
196enum Assert {
197    /// `^`, the start of the subject. Not the start of a line: Redis does not
198    /// pass `REG_NEWLINE`, so a newline in the subject is an ordinary byte.
199    Start,
200    /// `$`, the end of the subject.
201    End,
202    /// `\b` when true, `\B` when false.
203    ///
204    /// TRE calls both of these true at the start of the subject and at a byte
205    /// it reads as the end, without looking at either side, so `\b` holds and
206    /// `\B` fails there whatever the neighbours are.
207    Word(bool),
208    /// `\<`, the first byte of a word.
209    StartOfWord,
210    /// `\>`, one past the last byte of a word.
211    EndOfWord,
212}
213
214/// One byte as a class, whatever NOCASE says.
215///
216/// TRE only folds a byte it read straight out of the pattern, because the fold
217/// lives in the branch of the parser that handles a plain byte. A byte that an
218/// escape produced never passes through there, so `\x41` under NOCASE is `A`
219/// and not `A` or `a`.
220fn raw(b: u8) -> Class {
221    let mut c = Class::empty();
222    c.set(b);
223    c
224}
225
226const fn is_word(b: u8) -> bool {
227    b.is_ascii_alphanumeric() || b == b'_'
228}
229
230impl Assert {
231    fn holds(self, hay: &[u8], at: usize) -> bool {
232        let before = at > 0 && is_word(hay[at - 1]);
233        let after = at < hay.len() && is_word(hay[at]);
234        match self {
235            Assert::Start => at == 0,
236            Assert::End => at == hay.len(),
237            // TRE decides these by reading the byte ahead and comparing it
238            // against nul, so the end of the subject and a nul byte inside it
239            // look the same, and the start is not looked at either way.
240            Assert::Word(want) => {
241                let edge = at == 0 || at == hay.len() || hay[at] == 0;
242                (edge || before != after) == want
243            }
244            Assert::StartOfWord => !before && after,
245            Assert::EndOfWord => before && !after,
246        }
247    }
248}
249
250/// One step of the compiled program.
251#[derive(Clone, Copy, Debug)]
252enum Inst {
253    /// Consume one byte in `classes[i]` and carry on at the next instruction.
254    Class(u32),
255    /// Be in both places at once.
256    Split(u32, u32),
257    /// Carry on somewhere else.
258    Jump(u32),
259    /// Carry on at the next instruction if the test holds.
260    Assert(Assert),
261    /// The pattern matched.
262    Match,
263}
264
265/// What the parser builds before anything is laid out.
266///
267/// A tree rather than instructions with holes to patch, because `{n,m}` is
268/// compiled by emitting the same subtree several times and a tree is the thing
269/// that can be walked twice.
270enum Ast {
271    Empty,
272    Class(Class),
273    Assert(Assert),
274    Concat(Vec<Ast>),
275    Alt(Vec<Ast>),
276    Repeat(Box<Ast>, u32, Option<u32>),
277}
278
279/// A compiled pattern.
280///
281/// Compiling allocates and matching does not, which is the split `ARGREP` wants:
282/// a pattern is compiled once when the command is parsed and then run against
283/// every element the range touches.
284#[derive(Debug)]
285pub struct Regex {
286    prog: Vec<Inst>,
287    classes: Vec<Class>,
288}
289
290impl Regex {
291    /// Compile `pattern` as an extended regular expression over bytes.
292    ///
293    /// `nocase` is `REG_ICASE`, and it is applied while the byte classes are
294    /// built rather than while matching, so it costs nothing per element.
295    ///
296    /// # Errors
297    ///
298    /// Any of [`Error`], carrying TRE's own message for the same mistake.
299    pub fn new(pattern: &[u8], nocase: bool) -> Result<Regex, Error> {
300        let mut p = Parser {
301            pat: pattern,
302            at: 0,
303            nocase,
304            newline: false,
305            depth: 0,
306            groups: 0,
307            backref: None,
308        };
309        let ast = p.alternation()?;
310        if p.at != pattern.len() {
311            // Nothing reaches this. A `)` with no `(` is a literal and every
312            // other exit from `alternation` is the end of the pattern, so this
313            // is a guard against a future change rather than a live path.
314            return Err(Error::BadPattern);
315        }
316        // Both backreference answers wait for the whole parse, because TRE
317        // decides them in regcomp after tre_parse has returned, so a mistake
318        // anywhere else in the pattern is reported instead of these.
319        if let Some(n) = p.backref {
320            if n > p.groups {
321                return Err(Error::BackRef);
322            }
323            return Err(Error::Unsupported);
324        }
325        let mut c = Compiler {
326            prog: Vec::new(),
327            classes: Vec::new(),
328        };
329        c.node(&ast)?;
330        c.push(Inst::Match)?;
331        Ok(Regex {
332            prog: c.prog,
333            classes: c.classes,
334        })
335    }
336
337    /// How many instructions the pattern compiled to, for the matcher's scratch.
338    #[must_use]
339    fn len(&self) -> usize {
340        self.prog.len()
341    }
342}
343
344/// The scratch a match needs, kept across calls.
345///
346/// `ARGREP` runs a predicate per visited element, so the three vectors are
347/// allocated once for the command rather than once per element. A `Matcher` can
348/// be used with any [`Regex`]; it grows to the largest one it has seen.
349#[derive(Default, Debug)]
350pub struct Matcher {
351    /// The states live at this position, and the ones live at the next.
352    now: Vec<u32>,
353    next: Vec<u32>,
354    /// The stamp each state was last added under, so that adding a state
355    /// twice in one step is a comparison rather than a search.
356    seen: Vec<u64>,
357    /// The stack the epsilon closure walks with, so it is not the call stack.
358    work: Vec<u32>,
359    stamp: u64,
360}
361
362impl Matcher {
363    /// A matcher with nothing allocated yet.
364    #[must_use]
365    pub fn new() -> Matcher {
366        Matcher::default()
367    }
368
369    /// Grows the scratch to what `re` will need, so that matching never does.
370    ///
371    /// A state is added at most once per step, so none of the four vectors can
372    /// go past the program size. Doing the growth here means the caller can put
373    /// every allocation `ARGREP` makes in the part of the command that reads the
374    /// arguments, and the walk over the elements allocates nothing at all.
375    pub fn reserve(&mut self, re: &Regex) {
376        let n = re.len();
377        if self.seen.len() < n {
378            self.seen.resize(n, 0);
379        }
380        for v in [&mut self.now, &mut self.next, &mut self.work] {
381            v.reserve_exact(n.saturating_sub(v.capacity()));
382        }
383    }
384
385    /// Whether `re` matches anywhere in `hay`.
386    ///
387    /// Unanchored, which is what `regexec` without an anchor does and what
388    /// `ARGREP RE` means: the pattern has to match some run of bytes, not the
389    /// whole element.
390    ///
391    /// The walk is a Thompson simulation. Every state that could be live at a
392    /// position is live at once, so a byte is looked at exactly once and the
393    /// cost is the subject length times the program size in the worst case,
394    /// with no backtracking and therefore no pattern that makes it exponential.
395    pub fn is_match(&mut self, re: &Regex, hay: &[u8]) -> bool {
396        let n = re.len();
397        if self.seen.len() < n {
398            self.seen.resize(n, 0);
399        }
400        self.now.clear();
401        self.next.clear();
402        self.stamp += 1;
403        let mut stamp = self.stamp;
404
405        for at in 0..=hay.len() {
406            // Start a fresh attempt at every position, which is what makes the
407            // search unanchored without a `.*` in front of the program.
408            if add(
409                &mut self.now,
410                &mut self.seen,
411                &mut self.work,
412                stamp,
413                re,
414                hay,
415                at,
416                0,
417            ) {
418                return true;
419            }
420            if at == hay.len() {
421                break;
422            }
423            let byte = hay[at];
424            self.stamp += 1;
425            stamp = self.stamp;
426            self.next.clear();
427            for i in 0..self.now.len() {
428                let pc = self.now[i];
429                if let Inst::Class(c) = re.prog[pc as usize]
430                    && re.classes[c as usize].has(byte)
431                    && add(
432                        &mut self.next,
433                        &mut self.seen,
434                        &mut self.work,
435                        stamp,
436                        re,
437                        hay,
438                        at + 1,
439                        pc + 1,
440                    )
441                {
442                    return true;
443                }
444            }
445            core::mem::swap(&mut self.now, &mut self.next);
446        }
447        false
448    }
449}
450
451/// Add `pc` and everything reachable from it without consuming a byte.
452///
453/// Returns whether one of them was `Match`, which is the only answer `is_match`
454/// needs, so the walk stops the moment it is true rather than finishing the
455/// subject.
456#[allow(clippy::too_many_arguments)]
457fn add(
458    list: &mut Vec<u32>,
459    seen: &mut [u64],
460    work: &mut Vec<u32>,
461    stamp: u64,
462    re: &Regex,
463    hay: &[u8],
464    at: usize,
465    pc: u32,
466) -> bool {
467    work.clear();
468    work.push(pc);
469    while let Some(pc) = work.pop() {
470        let i = pc as usize;
471        if seen[i] == stamp {
472            continue;
473        }
474        seen[i] = stamp;
475        match re.prog[i] {
476            Inst::Class(_) => list.push(pc),
477            Inst::Split(a, b) => {
478                work.push(b);
479                work.push(a);
480            }
481            Inst::Jump(a) => work.push(a),
482            Inst::Assert(a) => {
483                if a.holds(hay, at) {
484                    work.push(pc + 1);
485                }
486            }
487            Inst::Match => return true,
488        }
489    }
490    false
491}
492
493// ---------------------------------------------------------------------------
494// Parsing
495// ---------------------------------------------------------------------------
496
497struct Parser<'a> {
498    pat: &'a [u8],
499    at: usize,
500    nocase: bool,
501    /// Whether `.` skips a newline, which only `(?n)` can turn on because
502    /// Redis never passes `REG_NEWLINE` itself.
503    newline: bool,
504    depth: u32,
505    /// How many groups the pattern has opened so far.
506    groups: u32,
507    /// The highest backreference seen, if any.
508    ///
509    /// Whether one is valid is not known until the whole pattern has been read,
510    /// because a reference may point forwards: `\1(a)` is a reference to a
511    /// group that has not been written down yet and TRE takes it.
512    backref: Option<u32>,
513}
514
515impl Parser<'_> {
516    fn peek(&self) -> Option<u8> {
517        self.pat.get(self.at).copied()
518    }
519
520    fn eat(&mut self, b: u8) -> bool {
521        if self.peek() == Some(b) {
522            self.at += 1;
523            return true;
524        }
525        false
526    }
527
528    /// `branch ('|' branch)*`
529    fn alternation(&mut self) -> Result<Ast, Error> {
530        let mut arms = vec![self.branch()?];
531        while self.eat(b'|') {
532            arms.push(self.branch()?);
533        }
534        if arms.len() == 1 {
535            return Ok(arms.pop().expect("one arm"));
536        }
537        Ok(Ast::Alt(arms))
538    }
539
540    /// A run of repeated atoms, up to a `|` or a closing `)` or the end.
541    ///
542    /// An empty branch is allowed, so `a|` matches `a` or nothing and `()` is a
543    /// group that matches nothing, both of which TRE accepts.
544    fn branch(&mut self) -> Result<Ast, Error> {
545        let mut parts: Vec<Ast> = Vec::new();
546        loop {
547            match self.peek() {
548                None | Some(b'|') => break,
549                // A `)` only ends the branch when a `(` is waiting for it.
550                // Outside a group it is an ordinary byte, which is why `a)b`
551                // matches the three bytes it looks like rather than failing.
552                Some(b')') if self.depth > 0 => break,
553                _ => {}
554            }
555            // A repetition operator with nothing in front of it repeats an atom
556            // that matches the empty string, which is what TRE's parser hands
557            // back when it is asked for an atom and finds an operator. So `*a`
558            // is `a`, and `{2}a` is `a` rather than `aa`.
559            let atom = match self.peek() {
560                Some(b'*' | b'+' | b'?' | b'{') => Ast::Empty,
561                _ => self.atom()?,
562            };
563            parts.push(self.repeats(atom)?);
564        }
565        match parts.len() {
566            0 => Ok(Ast::Empty),
567            1 => Ok(parts.pop().expect("one part")),
568            _ => Ok(Ast::Concat(parts)),
569        }
570    }
571
572    /// Every repetition operator that follows an atom, applied outwards.
573    ///
574    /// A second operator straight after the first is reserved in TRE and
575    /// refused, so `a**` and `a{2}+` are both errors, with one exception: a `?`
576    /// asks for the shortest match rather than the longest. That changes where
577    /// a match ends and not whether there is one, so for a yes or no answer it
578    /// is read and dropped.
579    fn repeats(&mut self, mut node: Ast) -> Result<Ast, Error> {
580        loop {
581            let (min, max) = match self.peek() {
582                Some(b'*') => {
583                    self.at += 1;
584                    (0, None)
585                }
586                Some(b'+') => {
587                    self.at += 1;
588                    (1, None)
589                }
590                Some(b'?') => {
591                    self.at += 1;
592                    (0, Some(1))
593                }
594                Some(b'{') => {
595                    self.at += 1;
596                    self.bound()?
597                }
598                _ => return Ok(node),
599            };
600            match self.peek() {
601                Some(b'?') => self.at += 1,
602                Some(b'*' | b'+') => return Err(Error::BadRepeat),
603                _ => {}
604            }
605            node = Ast::Repeat(Box::new(node), min, max);
606        }
607    }
608
609    /// The inside of a bound, with the `{` already eaten.
610    ///
611    /// A count is optional on both sides of the comma, so `{,3}` is `{0,3}` and
612    /// `{2,}` has no ceiling, and a missing count on both sides with no comma
613    /// at all is the empty `{}`, which is an error. The three ways this can go
614    /// wrong are told apart by where the parse stopped: off the end of the
615    /// pattern is a missing brace, stopped without having read anything is an
616    /// empty bound, and stopped on something that is not a brace is a bound
617    /// with rubbish in it.
618    fn bound(&mut self) -> Result<(u32, Option<u32>), Error> {
619        let start = self.at;
620        let mut min: i64 = self.number().map_or(-1, i64::from);
621        let mut max = min;
622        if self.eat(b',') {
623            if min < 0 {
624                min = 0;
625            }
626            max = self.number().map_or(-1, i64::from);
627        }
628        // Both of these are decided before the brace is looked for, so `{3,2`
629        // is a backwards bound rather than a missing brace.
630        if max >= 0 && min > max {
631            return Err(Error::BadBrace);
632        }
633        if min > i64::from(DUP_MAX) || max > i64::from(DUP_MAX) {
634            return Err(Error::BadMax);
635        }
636        // TRE walks past spaces and further commas on its way to the brace, so
637        // `{2, }` and `{2,,}` are the same bound as `{2,}`.
638        while matches!(self.peek(), Some(b' ' | b',')) {
639            self.at += 1;
640        }
641        if self.at >= self.pat.len() {
642            return Err(Error::MissingBrace);
643        }
644        if self.at == start {
645            return Err(Error::BadBrace);
646        }
647        if !self.eat(b'}') {
648            return Err(Error::BadBrace);
649        }
650        if min < 0 {
651            // No count on either side and no comma, which after the parameters
652            // TRE allows here would be `{~2}` and friends. Those repeat once.
653            min = 1;
654            max = 1;
655        }
656        Ok((min as u32, if max < 0 { None } else { Some(max as u32) }))
657    }
658
659    fn number(&mut self) -> Option<u32> {
660        let start = self.at;
661        let mut n: u32 = 0;
662        while let Some(b) = self.peek() {
663            if !b.is_ascii_digit() {
664                break;
665            }
666            // A bound past DUP_MAX is refused anyway, so saturating here keeps
667            // a long run of digits from wrapping into a small number.
668            n = n.saturating_mul(10).saturating_add(u32::from(b - b'0'));
669            self.at += 1;
670        }
671        if self.at == start { None } else { Some(n) }
672    }
673
674    fn atom(&mut self) -> Result<Ast, Error> {
675        let b = self.peek().ok_or(Error::BadPattern)?;
676        match b {
677            b'(' => {
678                self.at += 1;
679                if self.eat(b'?') {
680                    return self.extension();
681                }
682                self.groups += 1;
683                self.group()
684            }
685            b'.' => {
686                self.at += 1;
687                let mut c = Class::all();
688                if self.newline {
689                    c.clear(b'\n');
690                }
691                Ok(Ast::Class(c))
692            }
693            b'^' => {
694                self.at += 1;
695                Ok(Ast::Assert(Assert::Start))
696            }
697            b'$' => {
698                self.at += 1;
699                Ok(Ast::Assert(Assert::End))
700            }
701            b'[' => {
702                self.at += 1;
703                self.bracket()
704            }
705            b'\\' => {
706                self.at += 1;
707                self.escape()
708            }
709            // Everything else is the byte, including a `)` with no `(` and a
710            // `]` with no `[`.
711            _ => {
712                self.at += 1;
713                Ok(Ast::Class(self.literal(b)))
714            }
715        }
716    }
717
718    /// Everything up to the `)` that closes a group whose `(` is already eaten.
719    fn group(&mut self) -> Result<Ast, Error> {
720        self.depth += 1;
721        if self.depth > DEPTH_MAX {
722            return Err(Error::Space);
723        }
724        let inner = self.alternation()?;
725        self.depth -= 1;
726        if !self.eat(b')') {
727            return Err(Error::MissingParen);
728        }
729        Ok(inner)
730    }
731
732    /// TRE's `(?...)` extensions, with the `(?` already eaten.
733    ///
734    /// The letters turn compile flags on, and a `-` turns the rest of them off
735    /// again. A `:` then opens a group that does not capture, while a `)` or a
736    /// `#` comment ends the extension and leaves the flags on for the rest of
737    /// whatever encloses it. That last part is worth reading twice: TRE parses
738    /// the remainder as a whole expression under the new flags, so `a(?i)b|c`
739    /// is `a` followed by `b|c` rather than `ab` or `c`. Anything else is
740    /// "Invalid regexp", which is why `(?x)` is refused.
741    fn extension(&mut self) -> Result<Ast, Error> {
742        let (nocase, newline) = (self.nocase, self.newline);
743        let mut on = true;
744        let opens = loop {
745            match self.peek().ok_or(Error::BadPattern)? {
746                b'i' => self.nocase = on,
747                b'n' => self.newline = on,
748                // Right associativity and ungreedy decide which match is
749                // reported rather than whether there is one, and Redis asks
750                // only whether there is one, so these are read and dropped.
751                b'r' | b'U' => {}
752                b'-' => on = false,
753                b':' => {
754                    self.at += 1;
755                    break true;
756                }
757                b'#' => {
758                    // A comment is every byte up to the first `)`.
759                    while self.peek().is_some_and(|b| b != b')') {
760                        self.at += 1;
761                    }
762                    if !self.eat(b')') {
763                        return Err(Error::BadPattern);
764                    }
765                    break false;
766                }
767                b')' => {
768                    self.at += 1;
769                    break false;
770                }
771                _ => return Err(Error::BadPattern),
772            }
773            self.at += 1;
774        };
775        let inner = if opens {
776            self.group()?
777        } else {
778            self.alternation()?
779        };
780        self.nocase = nocase;
781        self.newline = newline;
782        Ok(inner)
783    }
784
785    /// One byte as a class, case folded if `nocase`.
786    fn literal(&self, b: u8) -> Class {
787        let mut c = raw(b);
788        if self.nocase {
789            c.fold_case();
790        }
791        c
792    }
793
794    /// What follows a backslash outside a bracket expression.
795    ///
796    /// TRE looks at this in two rounds and the order is what decides several
797    /// of the answers. First it checks a table of macros, which are letters
798    /// that stand for a short pattern and get parsed as if the client had
799    /// written that pattern out. Only if the letter is not a macro does it
800    /// reach the switch that has the word boundaries, `\x` and backreferences
801    /// in it. That is why `\d` is the digit class rather than backreference
802    /// number thirteen, and it is why `\n` is a newline rather than the letter.
803    fn escape(&mut self) -> Result<Ast, Error> {
804        let b = self.peek().ok_or(Error::TrailingBackslash)?;
805        if let Some(node) = self.macro_for(b) {
806            self.at += 1;
807            return Ok(node);
808        }
809        self.at += 1;
810        match b {
811            b'b' => Ok(Ast::Assert(Assert::Word(true))),
812            b'B' => Ok(Ast::Assert(Assert::Word(false))),
813            b'<' => Ok(Ast::Assert(Assert::StartOfWord)),
814            b'>' => Ok(Ast::Assert(Assert::EndOfWord)),
815            b'x' => self.hex(),
816            // A digit is a backreference, which needs the engine to remember
817            // what a group matched and a set of live states cannot. Note it and
818            // carry on: whether it is refused, and with which of two sentences,
819            // is decided once the pattern has been read to the end.
820            b'0'..=b'9' => {
821                let n = u32::from(b - b'0');
822                self.backref = Some(self.backref.map_or(n, |m| m.max(n)));
823                Ok(Ast::Empty)
824            }
825            // Anything else is the byte itself, so `\.` is a dot and `\\` is a
826            // backslash. Not folded: see `raw`.
827            _ => Ok(Ast::Class(raw(b))),
828        }
829    }
830
831    /// TRE's macro table, from `tre_macros` in `deps/tre/lib/tre-parse.c`.
832    ///
833    /// Six of them are a control byte by another name and six are a character
834    /// class. TRE writes them out as source and parses that, so `\w` is
835    /// `[[:alnum:]_]` down to how a negation and NOCASE interact; building the
836    /// same byte set directly gets to the same place without a second parse.
837    fn macro_for(&self, b: u8) -> Option<Ast> {
838        let byte = |v: u8| Some(Ast::Class(raw(v)));
839        let class = |keep: fn(u8) -> bool, negate: bool| {
840            let mut c = Class::empty();
841            for x in 0..=255u8 {
842                if keep(x) {
843                    c.set(x);
844                }
845            }
846            if negate {
847                c.negate();
848            }
849            Some(Ast::Class(c))
850        };
851        // A space in TRE's `[[:space:]]` is the C locale's, which includes the
852        // vertical tab, so this is the same set the named class builds.
853        let space = |x: u8| x.is_ascii_whitespace() || x == 0x0b;
854        let word = |x: u8| x.is_ascii_alphanumeric() || x == b'_';
855        match b {
856            b't' => byte(b'\t'),
857            b'n' => byte(b'\n'),
858            b'r' => byte(b'\r'),
859            b'f' => byte(0x0c),
860            b'a' => byte(0x07),
861            b'e' => byte(0x1b),
862            b'w' => class(word, false),
863            b'W' => class(word, true),
864            b's' => class(space, false),
865            b'S' => class(space, true),
866            b'd' => class(|x| x.is_ascii_digit(), false),
867            b'D' => class(|x| x.is_ascii_digit(), true),
868            _ => None,
869        }
870    }
871
872    /// `\xNN` or `\x{NNNN}`, with the `x` already eaten.
873    ///
874    /// The braced form is a whole code point in TRE and this engine is bytes,
875    /// so anything past 255 is a class with nothing in it, which is what a byte
876    /// build of TRE ends up matching against: nothing. A bare `\x` at the end
877    /// of the pattern is a NUL, which is TRE's `tre_ast_new_literal(mem, 0, 0)`
878    /// rather than an error.
879    fn hex(&mut self) -> Result<Ast, Error> {
880        let one = |v: u32| {
881            let mut c = Class::empty();
882            if v <= 255 {
883                c.set(v as u8);
884            }
885            c
886        };
887        if !self.eat(b'{') {
888            let mut v: u32 = 0;
889            for _ in 0..2 {
890                match self.peek().and_then(|b| (b as char).to_digit(16)) {
891                    Some(d) => {
892                        v = v * 16 + d;
893                        self.at += 1;
894                    }
895                    None => break,
896                }
897            }
898            return Ok(Ast::Class(one(v)));
899        }
900        // TRE reads at most eight hex digits and anything that is not one, and
901        // is not the closing brace, ends the pattern rather than the number.
902        let mut v: u32 = 0;
903        let mut digits = 0;
904        loop {
905            match self.peek() {
906                Some(b'}') => {
907                    self.at += 1;
908                    return Ok(Ast::Class(one(v)));
909                }
910                Some(b) => match (b as char).to_digit(16) {
911                    Some(d) if digits < 8 => {
912                        v = v * 16 + d;
913                        digits += 1;
914                        self.at += 1;
915                    }
916                    // Past eight digits TRE stops storing but keeps reading,
917                    // so the value is the first eight and the rest is skipped.
918                    Some(_) => self.at += 1,
919                    None => return Err(Error::MissingBrace),
920                },
921                None => return Err(Error::MissingBrace),
922            }
923        }
924    }
925
926    /// A bracket expression, with the `[` already eaten.
927    ///
928    /// The rules are all about position rather than about escaping: a `]` first
929    /// is a literal, a `^` first negates, a `-` first or last is a literal, and
930    /// a backslash is a backslash rather than an escape. That last one is what
931    /// catches people, and it is what TRE does.
932    ///
933    /// The order the three item shapes are tried in matters, because a range is
934    /// looked for before anything else. That is why `[]-a]` is the range from
935    /// `]` to `a` and not an empty expression, and why `[a-[:x:]]` is a range
936    /// whose ends are the wrong way round rather than a class.
937    fn bracket(&mut self) -> Result<Ast, Error> {
938        let mut class = Class::empty();
939        let negate = self.eat(b'^');
940        let first = self.at;
941        loop {
942            let b = self.peek().ok_or(Error::MissingBracket)?;
943            if b == b']' && self.at > first {
944                self.at += 1;
945                break;
946            }
947            // A range needs a `-` and something after it that is not the `]`
948            // closing the expression, so `[a-]` is an a and a dash.
949            let dash = self.pat.get(self.at + 1) == Some(&b'-');
950            let hi = self.pat.get(self.at + 2).copied();
951            if dash && hi.is_some_and(|h| h != b']') {
952                let hi = hi.expect("checked");
953                if b > hi {
954                    return Err(Error::BadRange);
955                }
956                class.set_range(b, hi);
957                self.at += 3;
958                continue;
959            }
960            if b == b'[' {
961                match self.pat.get(self.at + 1) {
962                    Some(b'.') | Some(b'=') => return Err(Error::Collate),
963                    Some(b':') => {
964                        self.named_class(&mut class)?;
965                        continue;
966                    }
967                    _ => {}
968                }
969            }
970            // A dash that is not the first item and could have opened a range
971            // has already had its left end taken by the range before it, and
972            // TRE's own comment for this is that two ranges are not allowed to
973            // share an endpoint. So `[a-c-e]` is refused while `[a-c-]` is not.
974            if b == b'-'
975                && self.at != first
976                && self.pat.get(self.at + 1).is_some_and(|&n| n != b']')
977            {
978                return Err(Error::BadRange);
979            }
980            class.set(b);
981            self.at += 1;
982        }
983        if self.nocase {
984            class.fold_case();
985        }
986        if negate {
987            class.negate();
988        }
989        Ok(Ast::Class(class))
990    }
991
992    /// `[:name:]` inside a bracket expression, with the `[` at the cursor.
993    fn named_class(&mut self, class: &mut Class) -> Result<(), Error> {
994        let start = self.at + 2;
995        let mut end = start;
996        while end < self.pat.len() && self.pat[end] != b':' {
997            end += 1;
998        }
999        if end + 1 >= self.pat.len() || self.pat[end + 1] != b']' {
1000            return Err(Error::CharClass);
1001        }
1002        let name = &self.pat[start..end];
1003        let keep: fn(u8) -> bool = match name {
1004            b"alnum" => |b| b.is_ascii_alphanumeric(),
1005            b"alpha" => |b| b.is_ascii_alphabetic(),
1006            // No `blank`. TRE has eleven classes and that is not one of them,
1007            // so `[[:blank:]]` is an unknown class name rather than a space and
1008            // a tab.
1009            b"cntrl" => |b| b.is_ascii_control(),
1010            b"digit" => |b| b.is_ascii_digit(),
1011            b"graph" => |b| b.is_ascii_graphic(),
1012            b"lower" => |b| b.is_ascii_lowercase(),
1013            b"print" => |b| b.is_ascii_graphic() || b == b' ',
1014            b"punct" => |b| b.is_ascii_punctuation(),
1015            b"space" => |b| b.is_ascii_whitespace() || b == 0x0b,
1016            b"upper" => |b| b.is_ascii_uppercase(),
1017            b"xdigit" => |b| b.is_ascii_hexdigit(),
1018            _ => return Err(Error::CharClass),
1019        };
1020        for b in 0..=255u8 {
1021            if keep(b) {
1022                class.set(b);
1023            }
1024        }
1025        self.at = end + 2;
1026        Ok(())
1027    }
1028}
1029
1030// ---------------------------------------------------------------------------
1031// Compiling
1032// ---------------------------------------------------------------------------
1033
1034struct Compiler {
1035    prog: Vec<Inst>,
1036    classes: Vec<Class>,
1037}
1038
1039/// Whether the node has a path through it that consumes no bytes.
1040fn matches_empty(ast: &Ast) -> bool {
1041    match ast {
1042        Ast::Empty | Ast::Assert(_) => true,
1043        Ast::Class(_) => false,
1044        Ast::Concat(parts) => parts.iter().all(matches_empty),
1045        Ast::Alt(arms) => arms.iter().any(matches_empty),
1046        Ast::Repeat(inner, min, _) => *min == 0 || matches_empty(inner),
1047    }
1048}
1049
1050impl Compiler {
1051    fn push(&mut self, i: Inst) -> Result<u32, Error> {
1052        if self.prog.len() >= PROG_MAX {
1053            return Err(Error::Space);
1054        }
1055        self.prog.push(i);
1056        Ok(self.prog.len() as u32 - 1)
1057    }
1058
1059    fn here(&self) -> u32 {
1060        self.prog.len() as u32
1061    }
1062
1063    fn class(&mut self, c: Class) -> Result<(), Error> {
1064        // The same class twice is one entry, which matters for `{n,m}` because
1065        // the expansion emits the same subtree over and over.
1066        let idx = match self.classes.iter().position(|&e| e == c) {
1067            Some(i) => i as u32,
1068            None => {
1069                self.classes.push(c);
1070                self.classes.len() as u32 - 1
1071            }
1072        };
1073        self.push(Inst::Class(idx))?;
1074        Ok(())
1075    }
1076
1077    fn node(&mut self, ast: &Ast) -> Result<(), Error> {
1078        match ast {
1079            Ast::Empty => Ok(()),
1080            Ast::Class(c) => self.class(*c),
1081            Ast::Assert(a) => {
1082                self.push(Inst::Assert(*a))?;
1083                Ok(())
1084            }
1085            Ast::Concat(parts) => {
1086                for p in parts {
1087                    self.node(p)?;
1088                }
1089                Ok(())
1090            }
1091            Ast::Alt(arms) => self.alt(arms),
1092            Ast::Repeat(inner, min, max) => self.repeat(inner, *min, *max),
1093        }
1094    }
1095
1096    /// `a|b|c` as a chain of splits, each arm jumping to the same place after.
1097    fn alt(&mut self, arms: &[Ast]) -> Result<(), Error> {
1098        let mut ends = Vec::with_capacity(arms.len());
1099        for (i, arm) in arms.iter().enumerate() {
1100            if i + 1 == arms.len() {
1101                self.node(arm)?;
1102                break;
1103            }
1104            let split = self.push(Inst::Split(0, 0))?;
1105            let first = self.here();
1106            self.node(arm)?;
1107            ends.push(self.push(Inst::Jump(0))?);
1108            let second = self.here();
1109            self.prog[split as usize] = Inst::Split(first, second);
1110        }
1111        let after = self.here();
1112        for j in ends {
1113            self.prog[j as usize] = Inst::Jump(after);
1114        }
1115        Ok(())
1116    }
1117
1118    /// A repetition, by emitting the subtree as many times as it can run.
1119    ///
1120    /// `a{2,4}` becomes `aa a? a?`, which is the same language: concatenation is
1121    /// contiguous, so a skipped optional cannot be made up by a later one.
1122    /// `a{2,}` becomes `aa a*`. This is why `PROG_MAX` exists.
1123    fn repeat(&mut self, inner: &Ast, min: u32, max: Option<u32>) -> Result<(), Error> {
1124        // A body that can match the empty string always runs at least once in
1125        // TRE, because its assertions sit on the transitions the skip would go
1126        // through. For a body with no assertions that changes nothing, since
1127        // the extra pass can match nothing. For one with them it is the whole
1128        // difference: `^*a` does not match "*a" and `x\b?y` does not match
1129        // "xy". The one exception is `{0}`, which TRE turns into an explicit
1130        // empty node that throws the operand away, and which lands in the
1131        // `Some(0)` arm below having emitted nothing at all.
1132        let min = if min == 0 && max != Some(0) && matches_empty(inner) {
1133            1
1134        } else {
1135            min
1136        };
1137        for _ in 0..min {
1138            self.node(inner)?;
1139        }
1140        match max {
1141            None => {
1142                // `x*`: split forwards or into the body, and loop back.
1143                let split = self.push(Inst::Split(0, 0))?;
1144                let body = self.here();
1145                self.node(inner)?;
1146                self.push(Inst::Jump(split))?;
1147                let after = self.here();
1148                self.prog[split as usize] = Inst::Split(body, after);
1149                Ok(())
1150            }
1151            Some(max) => {
1152                let mut splits = Vec::new();
1153                for _ in min..max {
1154                    let split = self.push(Inst::Split(0, 0))?;
1155                    let body = self.here();
1156                    self.prog[split as usize] = Inst::Split(body, 0);
1157                    splits.push(split);
1158                    self.node(inner)?;
1159                }
1160                // Every optional copy skips to the same place, which is the end
1161                // of the last one.
1162                let after = self.here();
1163                for s in splits {
1164                    let Inst::Split(body, _) = self.prog[s as usize] else {
1165                        unreachable!("only splits were recorded")
1166                    };
1167                    self.prog[s as usize] = Inst::Split(body, after);
1168                }
1169                Ok(())
1170            }
1171        }
1172    }
1173}
1174
1175#[cfg(test)]
1176mod tests {
1177    use super::*;
1178
1179    fn hits(pattern: &str, subject: &str) -> bool {
1180        let re = Regex::new(pattern.as_bytes(), false).expect("compiles");
1181        Matcher::new().is_match(&re, subject.as_bytes())
1182    }
1183
1184    fn hits_nocase(pattern: &str, subject: &str) -> bool {
1185        let re = Regex::new(pattern.as_bytes(), true).expect("compiles");
1186        Matcher::new().is_match(&re, subject.as_bytes())
1187    }
1188
1189    fn refuses(pattern: &str) -> Error {
1190        Regex::new(pattern.as_bytes(), false).expect_err("refused")
1191    }
1192
1193    #[test]
1194    fn a_literal_matches_anywhere_in_the_subject() {
1195        assert!(hits("abc", "abc"));
1196        assert!(hits("abc", "xxabcxx"));
1197        assert!(!hits("abc", "ab"));
1198        assert!(hits("", ""));
1199        assert!(hits("", "anything"));
1200    }
1201
1202    #[test]
1203    fn the_anchors_are_the_ends_of_the_subject_and_not_of_a_line() {
1204        assert!(hits("^abc", "abcdef"));
1205        assert!(!hits("^abc", "xabcdef"));
1206        assert!(hits("abc$", "xxabc"));
1207        assert!(!hits("abc$", "abcx"));
1208        assert!(hits("^abc$", "abc"));
1209        assert!(!hits("^abc$", "abc\n"));
1210        // No REG_NEWLINE, so a newline is an ordinary byte and `^` does not
1211        // start again after it.
1212        assert!(!hits("^b", "a\nb"));
1213        assert!(hits(".", "\n"));
1214    }
1215
1216    #[test]
1217    fn the_three_unbounded_repetitions_do_what_they_say() {
1218        assert!(hits("^ab*c$", "ac"));
1219        assert!(hits("^ab*c$", "abbbbc"));
1220        assert!(!hits("^ab+c$", "ac"));
1221        assert!(hits("^ab+c$", "abc"));
1222        assert!(hits("^ab?c$", "ac"));
1223        assert!(hits("^ab?c$", "abc"));
1224        assert!(!hits("^ab?c$", "abbc"));
1225        // A repetition that can match nothing, which is the shape that loops
1226        // forever in an engine that does not mark states as already added.
1227        assert!(hits("^(a*)*$", ""));
1228        assert!(hits("^(a*)*$", "aaa"));
1229    }
1230
1231    #[test]
1232    fn a_bound_counts_and_refuses_what_it_cannot_count() {
1233        assert!(hits("^a{3}$", "aaa"));
1234        assert!(!hits("^a{3}$", "aa"));
1235        assert!(!hits("^a{3}$", "aaaa"));
1236        assert!(hits("^a{2,}$", "aaaaa"));
1237        assert!(!hits("^a{2,}$", "a"));
1238        assert!(hits("^a{2,4}$", "aa"));
1239        assert!(hits("^a{2,4}$", "aaaa"));
1240        assert!(!hits("^a{2,4}$", "aaaaa"));
1241        assert!(hits("^a{0,2}$", ""));
1242        assert_eq!(refuses("a{3,2}"), Error::BadBrace);
1243        assert_eq!(refuses("a{256}"), Error::BadMax);
1244        assert_eq!(refuses("a{2"), Error::MissingBrace);
1245        assert_eq!(refuses("a{x}"), Error::BadBrace);
1246        // In atom position a brace is just a brace.
1247        assert!(hits("^[{]a$", "{a"));
1248    }
1249
1250    #[test]
1251    fn alternation_tries_every_arm_and_an_empty_arm_is_an_arm() {
1252        assert!(hits("^(cat|dog|bird)$", "dog"));
1253        assert!(!hits("^(cat|dog|bird)$", "cow"));
1254        assert!(hits("^(ab|a)b$", "ab"));
1255        assert!(hits("^(a|)$", ""));
1256        assert!(hits("^()$", ""));
1257        assert!(hits("^a(b|c)*d$", "abcbcd"));
1258    }
1259
1260    #[test]
1261    fn a_bracket_expression_follows_position_rather_than_escaping() {
1262        assert!(hits("^[abc]$", "b"));
1263        assert!(!hits("^[abc]$", "d"));
1264        assert!(hits("^[^abc]$", "d"));
1265        assert!(!hits("^[^abc]$", "a"));
1266        assert!(hits("^[a-z]+$", "hello"));
1267        assert!(!hits("^[a-z]+$", "Hello"));
1268        // A `]` first is a literal, a `-` first or last is a literal.
1269        assert!(hits("^[]a]$", "]"));
1270        assert!(hits("^[-a]$", "-"));
1271        assert!(hits("^[a-]$", "-"));
1272        assert!(hits("^[^]]$", "x"));
1273        // A backslash inside brackets is a backslash, which is the one that
1274        // catches people coming from a Perl style engine.
1275        assert!(hits("^[\\]$", "\\"));
1276        assert_eq!(refuses("[abc"), Error::MissingBracket);
1277        assert_eq!(refuses("[z-a]"), Error::BadRange);
1278        assert_eq!(refuses("[[.a.]]"), Error::Collate);
1279        assert_eq!(refuses("[[=a=]]"), Error::Collate);
1280    }
1281
1282    #[test]
1283    fn the_named_classes_are_the_posix_ones() {
1284        assert!(hits("^[[:digit:]]+$", "12345"));
1285        assert!(!hits("^[[:digit:]]+$", "12a45"));
1286        assert!(hits("^[[:alpha:][:digit:]]+$", "ab12"));
1287        assert!(hits("^[[:space:]]$", "\t"));
1288        assert!(hits("^[^[:alpha:]]$", "1"));
1289        assert!(hits("^[[:xdigit:]]+$", "deadBEEF01"));
1290        assert_eq!(refuses("[[:nosuch:]]"), Error::CharClass);
1291    }
1292
1293    #[test]
1294    fn the_escapes_are_tres_and_a_macro_beats_the_switch() {
1295        assert!(hits("^a\\.c$", "a.c"));
1296        assert!(!hits("^a\\.c$", "abc"));
1297        assert!(hits("^a\\*$", "a*"));
1298        assert!(hits("^\\x41$", "A"));
1299        assert!(hits("^\\x{41}$", "A"));
1300        // Past a byte there is no byte to match, so the class is empty.
1301        assert!(!hits("\\x{100}", "\u{100}"));
1302        assert!(!hits("\\x{100}", "\0"));
1303        // The six control macros.
1304        assert!(hits("^\\n$", "\n"));
1305        assert!(!hits("^\\n$", "n"));
1306        assert!(hits("^\\t\\r\\f\\a\\e$", "\t\r\x0c\x07\x1b"));
1307        // The six class macros, which the table reaches before the switch does,
1308        // so `\d` is a digit rather than backreference thirteen.
1309        assert!(hits("^\\d+$", "42"));
1310        assert!(!hits("^\\d+$", "4a"));
1311        assert!(hits("^\\D$", "a"));
1312        assert!(hits("^\\w+$", "a_1"));
1313        assert!(!hits("^\\w+$", "a-1"));
1314        assert!(hits("^\\W$", "-"));
1315        assert!(hits("^\\s+$", " \t\n"));
1316        assert!(hits("^\\S$", "x"));
1317        // And a macro is one atom, so a repetition applies to the whole class.
1318        assert!(hits("^\\d{3}$", "123"));
1319        assert_eq!(refuses("a\\"), Error::TrailingBackslash);
1320    }
1321
1322    #[test]
1323    fn a_backreference_is_refused_with_one_of_two_sentences() {
1324        // Pointing at a group that is not there is TRE's own error. Pointing at
1325        // one that is there compiles in TRE and is refused a step later, and
1326        // that step is the one whose sentence this carries.
1327        assert_eq!(refuses("(a)\\1"), Error::Unsupported);
1328        assert_eq!(refuses("(a)(b)\\2"), Error::Unsupported);
1329        assert_eq!(refuses("\\0"), Error::Unsupported);
1330        assert_eq!(refuses("\\1"), Error::BackRef);
1331        assert_eq!(refuses("(a)\\2"), Error::BackRef);
1332        // A reference may point forwards, so this one is valid and therefore
1333        // gets the second sentence rather than the first.
1334        assert_eq!(refuses("\\1(a)"), Error::Unsupported);
1335        // Both answers wait for the whole parse, so a mistake anywhere else in
1336        // the pattern is reported instead.
1337        assert_eq!(refuses("((a)\\9"), Error::MissingParen);
1338        assert_eq!(refuses("\\1a{256}"), Error::BadMax);
1339        assert_eq!(
1340            Error::Unsupported.as_str(),
1341            "regular expression backreferences are not supported"
1342        );
1343    }
1344
1345    #[test]
1346    fn a_backslash_in_a_bracket_expression_is_not_an_escape() {
1347        // The macros are expanded in atom position only, so inside brackets a
1348        // backslash is a backslash and `\d` is the two bytes it looks like.
1349        assert!(hits("^[\\d]+$", "\\d"));
1350        assert!(!hits("^[\\d]+$", "42"));
1351        assert!(hits("^[\\n]+$", "\\n"));
1352        assert!(!hits("^[\\n]$", "\n"));
1353    }
1354
1355    #[test]
1356    fn the_word_boundaries_look_at_both_sides() {
1357        assert!(hits("\\bcat\\b", "the cat sat"));
1358        assert!(!hits("\\bcat\\b", "concatenate"));
1359        assert!(hits("\\Bcat\\B", "concatenate"));
1360        assert!(!hits("\\Bcat\\B", "the cat sat"));
1361        assert!(hits("\\<cat", "a cat"));
1362        assert!(!hits("\\<cat", "concat"));
1363        assert!(hits("cat\\>", "concat"));
1364        assert!(!hits("cat\\>", "cats"));
1365        // The two ends of the subject are a boundary to TRE whatever sits next
1366        // to them, so `\b` holds there and `\B` fails there even between two
1367        // bytes that are not word bytes at all.
1368        assert!(hits("\\b-", "-a"));
1369        assert!(!hits("\\B-", "-a"));
1370        assert!(hits("-\\b", "a-"));
1371        assert!(!hits("-\\B", "a-"));
1372        assert!(!hits("-\\b-", "---"));
1373        assert!(hits("-\\B-", "---"));
1374        // A nul byte reads as the end for the same reason, because TRE decides
1375        // by comparing the byte ahead against nul rather than by counting.
1376        assert!(hits("\0\\b\0", "\0\0\0"));
1377        assert!(!hits("\0\\B\0", "\0\0\0"));
1378        // `\<` and `\>` are the ordinary ones and do look at both sides.
1379        assert!(hits("\\>", "a"));
1380        assert!(!hits("\\>", "-"));
1381        assert!(hits("\\<", "a"));
1382    }
1383
1384    #[test]
1385    fn nocase_folds_the_class_and_not_the_subject() {
1386        assert!(hits_nocase("^abc$", "ABC"));
1387        assert!(hits_nocase("^[a-c]+$", "ABC"));
1388        assert!(hits_nocase("^[A-C]+$", "abc"));
1389        // The fold happens before the negation, so a negated class refuses
1390        // both cases rather than refusing one and taking the other.
1391        assert!(!hits_nocase("^[^a]$", "A"));
1392        assert!(hits_nocase("^[^a]$", "b"));
1393        assert!(!hits_nocase("^abc$", "abd"));
1394        // A byte an escape produced is not folded, because the fold sits in
1395        // the branch of TRE's parser that reads a plain byte and an escape
1396        // never goes through it. This is the one place the register calls out,
1397        // because Redis's literal fast path does fold it.
1398        assert!(!hits_nocase("\\x41.", "ab"));
1399        assert!(hits_nocase("\\x41.", "Ab"));
1400        assert!(!hits_nocase("\\x{41}.", "ab"));
1401    }
1402
1403    #[test]
1404    fn the_inline_flags_are_read_and_scoped_the_way_tre_scopes_them() {
1405        assert!(hits("(?i)abc", "ABC"));
1406        assert!(hits("(?i)ABC", "abc"));
1407        assert!(hits("(?i:a)b", "Ab"));
1408        assert!(!hits("(?i:a)b", "AB"));
1409        assert!(hits_nocase("(?-i)A", "A"));
1410        assert!(!hits_nocase("(?-i)A", "a"));
1411        // The rest of the enclosing expression is parsed under the new flags
1412        // as a whole, so this is `a` followed by `b|c` rather than `ab` or `c`.
1413        assert!(hits("a(?i)b|c", "ac"));
1414        assert!(!hits("a(?i)b|c", "c"));
1415        // `(?n)` is the only flag with a second effect, and only on the dot,
1416        // because the matcher reads the outer flags when it decides an anchor.
1417        assert!(!hits("(?n).", "\n"));
1418        assert!(hits("(?n).", "a"));
1419        assert!(!hits("(?n)^b", "a\nb"));
1420        // A comment is dropped and the letters that only pick between matches
1421        // are read and ignored.
1422        assert!(hits("(?#a comment)abc", "abc"));
1423        assert!(hits("(?U)a", "a"));
1424        assert!(hits("(?r)a", "a"));
1425        // Anything else is refused, including a truncated one.
1426        assert_eq!(refuses("(?x)a"), Error::BadPattern);
1427        assert_eq!(refuses("(?"), Error::BadPattern);
1428        assert_eq!(refuses("(?ia)"), Error::BadPattern);
1429        assert_eq!(refuses("(?#unterminated"), Error::BadPattern);
1430    }
1431
1432    #[test]
1433    fn an_operator_with_nothing_in_front_of_it_repeats_nothing() {
1434        assert_eq!(refuses("(abc"), Error::MissingParen);
1435        // A `)` with no `(` is a byte, so this is a pattern about three bytes
1436        // rather than a mistake.
1437        assert!(hits("^a)b$", "a)b"));
1438        assert!(!hits("^a)b$", "ab"));
1439        assert!(hits("^(a)b$", "ab"));
1440        // A leading operator repeats an atom that matches the empty string.
1441        assert!(hits("^*a$", "a"));
1442        assert!(!hits("^*a$", "*a"));
1443        assert!(hits("^+a$", "a"));
1444        assert!(hits("^?a$", "a"));
1445        assert!(hits("^{2}a$", "a"));
1446        assert!(!hits("^{2}a$", "aa"));
1447        assert!(hits("^{,3}a$", "a"));
1448        // A `{` in that position is still a bound and still has to parse.
1449        assert_eq!(refuses("^{$"), Error::BadBrace);
1450        assert_eq!(refuses("{256}"), Error::BadMax);
1451        assert_eq!(refuses("{3,2}"), Error::BadBrace);
1452    }
1453
1454    #[test]
1455    fn a_repetition_of_something_that_matches_nothing_still_runs_once() {
1456        // The body of these repetitions can only match the empty string, so a
1457        // pass through it costs nothing, and TRE takes that pass rather than
1458        // the skip. Every assertion in the body therefore stays mandatory.
1459        assert!(!hits("x\\b?y", "xy"));
1460        assert!(!hits("x\\b{0,3}y", "xy"));
1461        assert!(!hits("x(\\b)*y", "xy"));
1462        assert!(!hits("x\\b?y", "x-y"));
1463        assert!(!hits("(^|a)*b", "cb"));
1464        assert!(hits("(^|a)*b", "ab"));
1465        assert!(!hits("(\\b*)*x", "yx"));
1466        assert!(hits("(\\b*)*x", "y x"));
1467        // A body that can match the empty string without asserting anything is
1468        // unaffected, because the extra pass matches nothing.
1469        assert!(hits("(a|)*b", "b"));
1470        assert!(hits("(a*|^)*b", "cb"));
1471        assert!(hits("(|^)*b", "cb"));
1472        assert!(hits("(a?)*b", "cb"));
1473        // A body that cannot match the empty string keeps its skip.
1474        assert!(hits("(a\\b)*c", "c"));
1475        // `{0}` is the exception: TRE throws the operand away entirely, so the
1476        // anchor is gone rather than mandatory.
1477        assert!(hits("^{0}a$", "*a"));
1478        assert!(hits("^{0}a", "*a"));
1479    }
1480
1481    #[test]
1482    fn a_second_repetition_operator_is_reserved_and_refused() {
1483        assert_eq!(refuses("a**"), Error::BadRepeat);
1484        assert_eq!(refuses("a*+"), Error::BadRepeat);
1485        assert_eq!(refuses("a+*"), Error::BadRepeat);
1486        assert_eq!(refuses("a?*"), Error::BadRepeat);
1487        assert_eq!(refuses("a?+"), Error::BadRepeat);
1488        assert_eq!(refuses("a{2}*"), Error::BadRepeat);
1489        assert_eq!(refuses("a{2}+"), Error::BadRepeat);
1490        // A `?` is the exception. It asks for the shortest match rather than
1491        // the longest, which changes nothing about whether there is one.
1492        assert!(hits("^a*?$", ""));
1493        assert!(hits("^a??$", ""));
1494        assert!(hits("^a{2}?$", "aa"));
1495        // A bound after anything is a repetition of a repetition, not a second
1496        // operator, so it counts rather than being refused.
1497        assert!(hits("^a{2}{3}$", "aaaaaa"));
1498        assert!(!hits("^a{2}{3}$", "aa"));
1499        assert!(hits("^a*{2}$", "aa"));
1500        assert!(hits("^a{1,2}{1,2}$", "aaaa"));
1501    }
1502
1503    #[test]
1504    fn nothing_a_pattern_can_do_makes_the_walk_more_than_linear() {
1505        // The shape that is exponential in a backtracking engine. If this ever
1506        // stops returning promptly, the simulation has grown a backtrack.
1507        let re = Regex::new(b"^(a+)+b$", false).expect("compiles");
1508        let mut m = Matcher::new();
1509        let subject = vec![b'a'; 4096];
1510        assert!(!m.is_match(&re, &subject));
1511        assert!(m.is_match(&re, b"aaaab"));
1512    }
1513
1514    #[test]
1515    fn a_pattern_that_would_compile_to_too_much_is_refused_rather_than_built() {
1516        // Each level multiplies, so three of them is sixteen million steps.
1517        assert_eq!(refuses("((a{255}){255}){255}"), Error::Space);
1518        // Deep nesting is refused before it reaches the parser's own stack.
1519        let deep = "(".repeat(200) + "a" + &")".repeat(200);
1520        assert_eq!(refuses(&deep), Error::Space);
1521        // And the thing just under the cap still compiles.
1522        assert!(Regex::new(b"(a{200}){200}", false).is_ok());
1523    }
1524
1525    #[test]
1526    fn one_matcher_serves_every_pattern_it_is_given() {
1527        // This is the shape ARGREP uses: several compiled patterns, one lot of
1528        // scratch, many subjects. The scratch grows to the largest program and
1529        // a smaller one afterwards must not read the leftovers as live states.
1530        let big = Regex::new(b"^(abc|def){2,8}$", false).expect("compiles");
1531        let small = Regex::new(b"^x$", false).expect("compiles");
1532        let mut m = Matcher::new();
1533        for _ in 0..4 {
1534            assert!(m.is_match(&big, b"abcdefabc"));
1535            assert!(m.is_match(&small, b"x"));
1536            assert!(!m.is_match(&small, b"y"));
1537            assert!(!m.is_match(&big, b"abcdefa"));
1538        }
1539    }
1540
1541    #[test]
1542    fn the_error_messages_are_the_ones_tre_would_have_printed() {
1543        assert_eq!(Error::MissingBracket.as_str(), "Missing ']'");
1544        assert_eq!(Error::MissingParen.as_str(), "Missing ')'");
1545        assert_eq!(Error::MissingBrace.as_str(), "Missing '}'");
1546        assert_eq!(Error::BadBrace.as_str(), "Invalid contents of {}");
1547        assert_eq!(Error::BadRange.as_str(), "Invalid character range");
1548        assert_eq!(Error::CharClass.as_str(), "Unknown character class name");
1549        assert_eq!(Error::Collate.as_str(), "Unknown collating element");
1550        assert_eq!(Error::TrailingBackslash.as_str(), "Trailing backslash");
1551        assert_eq!(
1552            Error::BadRepeat.as_str(),
1553            "Invalid use of repetition operators"
1554        );
1555        assert_eq!(
1556            Error::BadMax.as_str(),
1557            "Maximum repetition in {} larger than 255"
1558        );
1559        assert_eq!(Error::Space.as_str(), "Out of memory");
1560        assert_eq!(Error::BadPattern.as_str(), "Invalid regexp");
1561        assert_eq!(Error::BackRef.as_str(), "Invalid back reference");
1562    }
1563
1564    #[test]
1565    fn a_subject_is_bytes_and_not_text() {
1566        let re = Regex::new(b"^.{3}$", false).expect("compiles");
1567        let mut m = Matcher::new();
1568        // Three bytes of anything, including a NUL and the top of the range,
1569        // and a three byte character is three bytes rather than one.
1570        assert!(m.is_match(&re, &[0x00, 0xff, 0x80]));
1571        assert!(m.is_match(&re, "☃".as_bytes()));
1572        assert!(!m.is_match(&re, "ab".as_bytes()));
1573        let hi = Regex::new(&[b'^', 0xff, b'$'], false).expect("compiles");
1574        assert!(m.is_match(&hi, &[0xff]));
1575        assert!(!m.is_match(&hi, &[0xfe]));
1576    }
1577}