Skip to content

Commit e91f23b

Browse files
committed
sh: bypass REG_EMPTY for empty regexes on macos
1 parent dc726f9 commit e91f23b

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

sh/src/pattern/regex.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ fn regex_compilation_result(
3838

3939
// TODO: the implementation is copied from awk, maybe we should consider putting it in a shared crate
4040
pub struct Regex {
41-
raw_regex: libc::regex_t,
41+
/// if the regex was initialized with an empty string,
42+
/// `raw_regex` will be empty. This is to allow
43+
/// empty string regexes on MacOS, which otherwise
44+
/// would return a REG_EMPTY on compilation.
45+
raw_regex: Option<libc::regex_t>,
4246
regex_string: CString,
4347
}
4448

@@ -57,6 +61,9 @@ pub struct MatchIter<'a> {
5761
impl Iterator for MatchIter<'_> {
5862
type Item = RegexMatch;
5963
fn next(&mut self) -> Option<Self::Item> {
64+
if self.regex.raw_regex.is_none() {
65+
return None;
66+
}
6067
if self.next_start >= self.string.to_bytes().len() {
6168
return None;
6269
}
@@ -66,7 +73,7 @@ impl Iterator for MatchIter<'_> {
6673
};
6774
let exec_status = unsafe {
6875
libc::regexec(
69-
ptr::from_ref(&self.regex.raw_regex),
76+
ptr::from_ref(&self.regex.raw_regex.unwrap()),
7077
self.string.as_ptr().add(self.next_start),
7178
1,
7279
ptr::from_mut(&mut match_range),
@@ -87,13 +94,19 @@ impl Iterator for MatchIter<'_> {
8794

8895
impl Regex {
8996
pub fn new(regex: CString) -> Result<Self, String> {
97+
if regex.is_empty() {
98+
return Ok(Self {
99+
raw_regex: None,
100+
regex_string: regex,
101+
});
102+
}
90103
let mut raw = unsafe { std::mem::zeroed::<libc::regex_t>() };
91104
// difference from awk implementation: use 0 instead of REG_EXTENDED
92105
let compilation_status =
93106
unsafe { libc::regcomp(ptr::from_mut(&mut raw), regex.as_ptr(), 0) };
94107
regex_compilation_result(compilation_status, &raw)?;
95108
Ok(Self {
96-
raw_regex: raw,
109+
raw_regex: Some(raw),
97110
regex_string: regex,
98111
})
99112
}
@@ -113,8 +126,10 @@ impl Regex {
113126

114127
impl Drop for Regex {
115128
fn drop(&mut self) {
116-
unsafe {
117-
libc::regfree(ptr::from_mut(&mut self.raw_regex));
129+
if let Some(regex) = &mut self.raw_regex {
130+
unsafe {
131+
libc::regfree(ptr::from_mut(regex));
132+
}
118133
}
119134
}
120135
}

0 commit comments

Comments
 (0)