/rust/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/src/error.rs
Line  | Count  | Source  | 
1  |  | use alloc::string::{String, ToString}; | 
2  |  |  | 
3  |  | use regex_automata::meta;  | 
4  |  |  | 
5  |  | /// An error that occurred during parsing or compiling a regular expression.  | 
6  |  | #[non_exhaustive]  | 
7  |  | #[derive(Clone, PartialEq)]  | 
8  |  | pub enum Error { | 
9  |  |     /// A syntax error.  | 
10  |  |     Syntax(String),  | 
11  |  |     /// The compiled program exceeded the set size  | 
12  |  |     /// limit. The argument is the size limit imposed by  | 
13  |  |     /// [`RegexBuilder::size_limit`](crate::RegexBuilder::size_limit). Even  | 
14  |  |     /// when not configured explicitly, it defaults to a reasonable limit.  | 
15  |  |     ///  | 
16  |  |     /// If you're getting this error, it occurred because your regex has been  | 
17  |  |     /// compiled to an intermediate state that is too big. It is important to  | 
18  |  |     /// note that exceeding this limit does _not_ mean the regex is too big to  | 
19  |  |     /// _work_, but rather, the regex is big enough that it may wind up being  | 
20  |  |     /// surprisingly slow when used in a search. In other words, this error is  | 
21  |  |     /// meant to be a practical heuristic for avoiding a performance footgun,  | 
22  |  |     /// and especially so for the case where the regex pattern is coming from  | 
23  |  |     /// an untrusted source.  | 
24  |  |     ///  | 
25  |  |     /// There are generally two ways to move forward if you hit this error.  | 
26  |  |     /// The first is to find some way to use a smaller regex. The second is to  | 
27  |  |     /// increase the size limit via `RegexBuilder::size_limit`. However, if  | 
28  |  |     /// your regex pattern is not from a trusted source, then neither of these  | 
29  |  |     /// approaches may be appropriate. Instead, you'll have to determine just  | 
30  |  |     /// how big of a regex you want to allow.  | 
31  |  |     CompiledTooBig(usize),  | 
32  |  | }  | 
33  |  |  | 
34  |  | impl Error { | 
35  | 0  |     pub(crate) fn from_meta_build_error(err: meta::BuildError) -> Error { | 
36  | 0  |         if let Some(size_limit) = err.size_limit() { | 
37  | 0  |             Error::CompiledTooBig(size_limit)  | 
38  | 0  |         } else if let Some(ref err) = err.syntax_error() { | 
39  | 0  |             Error::Syntax(err.to_string())  | 
40  |  |         } else { | 
41  |  |             // This is a little suspect. Technically there are more ways for  | 
42  |  |             // a meta regex to fail to build other than "exceeded size limit"  | 
43  |  |             // and "syntax error." For example, if there are too many states  | 
44  |  |             // or even too many patterns. But in practice this is probably  | 
45  |  |             // good enough. The worst thing that happens is that Error::Syntax  | 
46  |  |             // represents an error that isn't technically a syntax error, but  | 
47  |  |             // the actual message will still be shown. So... it's not too bad.  | 
48  |  |             //  | 
49  |  |             // We really should have made the Error type in the regex crate  | 
50  |  |             // completely opaque. Rookie mistake.  | 
51  | 0  |             Error::Syntax(err.to_string())  | 
52  |  |         }  | 
53  | 0  |     }  | 
54  |  | }  | 
55  |  |  | 
56  |  | #[cfg(feature = "std")]  | 
57  |  | impl std::error::Error for Error { | 
58  |  |     // TODO: Remove this method entirely on the next breaking semver release.  | 
59  |  |     #[allow(deprecated)]  | 
60  | 0  |     fn description(&self) -> &str { | 
61  | 0  |         match *self { | 
62  | 0  |             Error::Syntax(ref err) => err,  | 
63  | 0  |             Error::CompiledTooBig(_) => "compiled program too big",  | 
64  |  |         }  | 
65  | 0  |     }  | 
66  |  | }  | 
67  |  |  | 
68  |  | impl core::fmt::Display for Error { | 
69  | 0  |     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | 
70  | 0  |         match *self { | 
71  | 0  |             Error::Syntax(ref err) => err.fmt(f),  | 
72  | 0  |             Error::CompiledTooBig(limit) => write!(  | 
73  | 0  |                 f,  | 
74  | 0  |                 "Compiled regex exceeds size limit of {limit} bytes.", | 
75  |  |             ),  | 
76  |  |         }  | 
77  | 0  |     }  | 
78  |  | }  | 
79  |  |  | 
80  |  | // We implement our own Debug implementation so that we show nicer syntax  | 
81  |  | // errors when people use `Regex::new(...).unwrap()`. It's a little weird,  | 
82  |  | // but the `Syntax` variant is already storing a `String` anyway, so we might  | 
83  |  | // as well format it nicely.  | 
84  |  | impl core::fmt::Debug for Error { | 
85  | 0  |     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | 
86  | 0  |         match *self { | 
87  | 0  |             Error::Syntax(ref err) => { | 
88  | 0  |                 let hr: String = core::iter::repeat('~').take(79).collect(); | 
89  | 0  |                 writeln!(f, "Syntax(")?; | 
90  | 0  |                 writeln!(f, "{hr}")?; | 
91  | 0  |                 writeln!(f, "{err}")?; | 
92  | 0  |                 writeln!(f, "{hr}")?; | 
93  | 0  |                 write!(f, ")")?;  | 
94  | 0  |                 Ok(())  | 
95  |  |             }  | 
96  | 0  |             Error::CompiledTooBig(limit) => { | 
97  | 0  |                 f.debug_tuple("CompiledTooBig").field(&limit).finish() | 
98  |  |             }  | 
99  |  |         }  | 
100  | 0  |     }  | 
101  |  | }  |