Skip to content

Commit 85ba8bd

Browse files
committed
Add validations for ERE quantifiers {m}, {m,} and {m,n}
1 parent b5b4cef commit 85ba8bd

File tree

8 files changed

+316
-30
lines changed

8 files changed

+316
-30
lines changed

src/sed/compiler.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ fn compile_sequence(
286286
let n_addr = compile_address_range(lines, line, &mut cmd, context)?;
287287
line.eat_spaces();
288288
let mut cmd_spec = get_verified_cmd_spec(lines, line, n_addr)?;
289-
290289
// Compile the command according to its specification.
291290
let mut cmd_mut = cmd.borrow_mut();
292291
cmd_mut.code = line.current();
@@ -331,10 +330,8 @@ fn compile_address_range(
331330
let mut is_line0 = false;
332331

333332
line.eat_spaces();
334-
if !line.eol()
335-
&& is_address_char(line.current())
336-
&& let Ok(addr1) = compile_address(lines, line, context)
337-
{
333+
if !line.eol() && is_address_char(line.current()) {
334+
let addr1 = compile_address(lines, line, context)?;
338335
is_line0 = matches!(addr1, Address::Line(0));
339336
cmd.addr1 = Some(addr1);
340337
if is_line0 && context.posix {
@@ -364,9 +361,8 @@ fn compile_address_range(
364361
}
365362

366363
// Look for second address.
367-
if !line.eol()
368-
&& let Ok(addr2) = compile_address(lines, line, context)
369-
{
364+
if !line.eol() {
365+
let addr2 = compile_address(lines, line, context)?;
370366
// Set step_n to the number specified in the (required numeric) address.
371367
let step_n = if is_step_match || is_step_end {
372368
match addr2 {
@@ -449,7 +445,7 @@ fn compile_address(
449445
// The next character is an arbitrary delimiter
450446
line.advance();
451447
}
452-
let re = parse_regex(lines, line)?;
448+
let re = parse_regex(lines, line, context.regex_extended)?;
453449
// Skip over delimiter
454450
line.advance();
455451

@@ -624,7 +620,7 @@ fn compile_regex(
624620

625621
// Convert basic to extended regular expression if needed.
626622
let pattern = if context.regex_extended {
627-
pattern
623+
&pattern.replace("{,}", "*")
628624
} else {
629625
&bre_to_ere(pattern)
630626
};
@@ -633,7 +629,7 @@ fn compile_regex(
633629
let pattern = if icase {
634630
format!("(?i){pattern}")
635631
} else {
636-
pattern.to_string()
632+
pattern.clone()
637633
};
638634

639635
// Compile into engine.
@@ -775,8 +771,7 @@ fn compile_subst_command(
775771
);
776772
}
777773

778-
let pattern = parse_regex(lines, line)?;
779-
774+
let pattern = parse_regex(lines, line, context.regex_extended)?;
780775
let mut subst = Box::new(Substitution::default());
781776

782777
subst.replacement = compile_replacement(lines, line)?;
@@ -806,7 +801,6 @@ fn compile_subst_command(
806801
),
807802
);
808803
}
809-
810804
cmd.data = CommandData::Substitution(subst);
811805

812806
parse_command_ending(lines, line, cmd)?;
@@ -1543,6 +1537,21 @@ mod tests {
15431537
assert!(!regex.is_match(&mut IOChunk::new_from_str("ABC")).unwrap());
15441538
}
15451539

1540+
#[test]
1541+
fn test_compile_re_extended() {
1542+
let (lines, chars) = make_providers("acaa\nbbb\nccc");
1543+
let mut ctx = ctx();
1544+
ctx.regex_extended = true;
1545+
let regex = compile_regex(&lines, &chars, "cc{,}", &ctx, false)
1546+
.unwrap()
1547+
.expect("regex should be present");
1548+
assert!(
1549+
regex
1550+
.is_match(&mut IOChunk::new_from_str("acaa\nccc"))
1551+
.unwrap()
1552+
);
1553+
}
1554+
15461555
#[test]
15471556
fn test_compile_re_case_insensitive() {
15481557
let (lines, chars) = dummy_providers();

0 commit comments

Comments
 (0)