1 #![cfg_attr(feature = "pattern", feature(pattern))]
5 // Due to macro scoping rules, this definition only applies for the modules
6 // defined below. Effectively, it allows us to use the same tests for both
7 // native and dynamic regexes.
9 // This is also used to test the various matching engines. This one exercises
10 // the normal code path which automatically chooses the engine based on the
11 // regex and the input. Other dynamic tests explicitly set the engine to use.
12 macro_rules
! regex_new
{
21 regex_new
!($re
).unwrap()
25 macro_rules
! regex_set_new
{
32 macro_rules
! regex_set
{
34 regex_set_new
!($res
).unwrap()
38 // Must come before other module definitions.
39 include
!("macros_str.rs");
40 include
!("macros.rs");
57 #[cfg(feature = "unicode")]
59 #[cfg(feature = "unicode-perl")]
61 #[cfg(feature = "unicode-perl")]
62 mod word_boundary_unicode
;
65 fn disallow_non_utf8() {
66 assert
!(regex
::Regex
::new(r
"(?-u)\xFF").is_err());
67 assert
!(regex
::Regex
::new(r
"(?-u).").is_err());
68 assert
!(regex
::Regex
::new(r
"(?-u)[\xFF]").is_err());
69 assert
!(regex
::Regex
::new(r
"(?-u)☃").is_err());
74 assert
!(regex
::Regex
::new(r
"\0").is_err());
79 assert
!(regex
::RegexBuilder
::new(r
"\0").octal(true).build().is_ok());
85 use regex
::{Regex, RegexBuilder, RegexSet, RegexSetBuilder}
;
86 use std
::panic
::{RefUnwindSafe, UnwindSafe}
;
88 fn assert_send
<T
: Send
>() {}
89 fn assert_sync
<T
: Sync
>() {}
90 fn assert_unwind_safe
<T
: UnwindSafe
>() {}
91 fn assert_ref_unwind_safe
<T
: RefUnwindSafe
>() {}
93 assert_send
::<Regex
>();
94 assert_sync
::<Regex
>();
95 assert_unwind_safe
::<Regex
>();
96 assert_ref_unwind_safe
::<Regex
>();
97 assert_send
::<RegexBuilder
>();
98 assert_sync
::<RegexBuilder
>();
99 assert_unwind_safe
::<RegexBuilder
>();
100 assert_ref_unwind_safe
::<RegexBuilder
>();
102 assert_send
::<bytes
::Regex
>();
103 assert_sync
::<bytes
::Regex
>();
104 assert_unwind_safe
::<bytes
::Regex
>();
105 assert_ref_unwind_safe
::<bytes
::Regex
>();
106 assert_send
::<bytes
::RegexBuilder
>();
107 assert_sync
::<bytes
::RegexBuilder
>();
108 assert_unwind_safe
::<bytes
::RegexBuilder
>();
109 assert_ref_unwind_safe
::<bytes
::RegexBuilder
>();
111 assert_send
::<RegexSet
>();
112 assert_sync
::<RegexSet
>();
113 assert_unwind_safe
::<RegexSet
>();
114 assert_ref_unwind_safe
::<RegexSet
>();
115 assert_send
::<RegexSetBuilder
>();
116 assert_sync
::<RegexSetBuilder
>();
117 assert_unwind_safe
::<RegexSetBuilder
>();
118 assert_ref_unwind_safe
::<RegexSetBuilder
>();
120 assert_send
::<bytes
::RegexSet
>();
121 assert_sync
::<bytes
::RegexSet
>();
122 assert_unwind_safe
::<bytes
::RegexSet
>();
123 assert_ref_unwind_safe
::<bytes
::RegexSet
>();
124 assert_send
::<bytes
::RegexSetBuilder
>();
125 assert_sync
::<bytes
::RegexSetBuilder
>();
126 assert_unwind_safe
::<bytes
::RegexSetBuilder
>();
127 assert_ref_unwind_safe
::<bytes
::RegexSetBuilder
>();
130 // See: https://github.com/rust-lang/regex/issues/568
132 fn oibits_regression() {
136 let _
= panic
::catch_unwind(|| Regex
::new("a").unwrap());
139 // See: https://github.com/rust-lang/regex/issues/750
141 #[cfg(target_pointer_width = "64")]
142 fn regex_is_reasonably_small() {
143 use std
::mem
::size_of
;
146 use regex
::{Regex, RegexSet}
;
148 assert_eq
!(16, size_of
::<Regex
>());
149 assert_eq
!(16, size_of
::<RegexSet
>());
150 assert_eq
!(16, size_of
::<bytes
::Regex
>());
151 assert_eq
!(16, size_of
::<bytes
::RegexSet
>());
154 // See: https://github.com/rust-lang/regex/security/advisories/GHSA-m5pq-gvj9-9vr8
155 // See: CVE-2022-24713
157 // We test that our regex compiler will correctly return a "too big" error when
158 // we try to use a very large repetition on an *empty* sub-expression.
160 // At the time this test was written, the regex compiler does not represent
161 // empty sub-expressions with any bytecode instructions. In effect, it's an
162 // "optimization" to leave them out, since they would otherwise correspond
163 // to an unconditional JUMP in the regex bytecode (i.e., an unconditional
164 // epsilon transition in the NFA graph). Therefore, an empty sub-expression
165 // represents an interesting case for the compiler's size limits. Since it
166 // doesn't actually contribute any additional memory to the compiled regex
167 // instructions, the size limit machinery never detects it. Instead, it just
168 // dumbly tries to compile the empty sub-expression N times, where N is the
171 // When N is very large, this will cause the compiler to essentially spin and
172 // do nothing for a decently large amount of time. It causes the regex to take
173 // quite a bit of time to compile, despite the concrete syntax of the regex
174 // being quite small.
176 // The degree to which this is actually a problem is somewhat of a judgment
177 // call. Some regexes simply take a long time to compile. But in general, you
178 // should be able to reasonably control this by setting lower or higher size
179 // limits on the compiled object size. But this mitigation doesn't work at all
182 // This particular test is somewhat narrow. It merely checks that regex
183 // compilation will, at some point, return a "too big" error. Before the
184 // fix landed, this test would eventually fail because the regex would be
185 // successfully compiled (after enough time elapsed). So while this test
186 // doesn't check that we exit in a reasonable amount of time, it does at least
187 // check that we are properly returning an error at some point.
189 fn big_empty_regex_fails() {
192 let result
= Regex
::new("(?:){4294967295}");
193 assert
!(result
.is_err());
196 // Below is a "billion laughs" variant of the previous test case.
198 fn big_empty_reps_chain_regex_fails() {
201 let result
= Regex
::new("(?:){64}{64}{64}{64}{64}{64}");
202 assert
!(result
.is_err());
205 // Below is another situation where a zero-length sub-expression can be
208 fn big_zero_reps_regex_fails() {
211 let result
= Regex
::new(r
"x{0}{4294967295}");
212 assert
!(result
.is_err());
215 // Testing another case for completeness.
217 fn empty_alt_regex_fails() {
220 let result
= Regex
::new(r
"(?:|){4294967295}");
221 assert
!(result
.is_err());