diff --git a/src/sed/compiler.rs b/src/sed/compiler.rs index bcfff31..20d416d 100644 --- a/src/sed/compiler.rs +++ b/src/sed/compiler.rs @@ -791,7 +791,7 @@ fn compile_subst_command( let mut subst = Box::new(Substitution::default()); subst.replacement = compile_replacement(lines, line)?; - compile_subst_flags(lines, line, &mut subst)?; + compile_subst_flags(lines, line, &mut subst, context)?; if pattern.is_empty() && subst.ignore_case { return compilation_error( @@ -865,6 +865,7 @@ pub fn compile_subst_flags( lines: &ScriptLineProvider, line: &mut ScriptCharProvider, subst: &mut Substitution, + context: &mut ProcessingContext, ) -> UResult<()> { let mut seen_g_or_n = false; @@ -899,10 +900,19 @@ pub fn compile_subst_flags( } 'i' | 'I' => { + if context.posix { + return compilation_error(lines, line, "unknown option to 's'"); + } subst.ignore_case = true; line.advance(); } + 'm' | 'M' | 'e' => { + if context.posix { + return compilation_error(lines, line, "unknown option to 's'"); + } + } + _c @ '1'..='9' => { if seen_g_or_n { return compilation_error( @@ -2033,7 +2043,7 @@ mod tests { let (lines, mut chars) = make_providers("g"); let mut subst = Substitution::default(); - compile_subst_flags(&lines, &mut chars, &mut subst).unwrap(); + compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap(); assert_eq!(subst.occurrence, 0); // 'g' means all occurrences } @@ -2042,7 +2052,7 @@ mod tests { let (lines, mut chars) = make_providers("p"); let mut subst = Substitution::default(); - compile_subst_flags(&lines, &mut chars, &mut subst).unwrap(); + compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap(); assert!(subst.print_flag); } @@ -2051,7 +2061,7 @@ mod tests { let (lines, mut chars) = make_providers("I"); let mut subst = Substitution::default(); - compile_subst_flags(&lines, &mut chars, &mut subst).unwrap(); + compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap(); assert!(subst.ignore_case); } @@ -2060,7 +2070,7 @@ mod tests { let (lines, mut chars) = make_providers("i"); let mut subst = Substitution::default(); - compile_subst_flags(&lines, &mut chars, &mut subst).unwrap(); + compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap(); assert!(subst.ignore_case); } @@ -2069,7 +2079,7 @@ mod tests { let (lines, mut chars) = make_providers("3"); let mut subst = Substitution::default(); - compile_subst_flags(&lines, &mut chars, &mut subst).unwrap(); + compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap(); assert_eq!(subst.occurrence, 3); } @@ -2078,7 +2088,7 @@ mod tests { let (lines, mut chars) = make_providers("g3"); let mut subst = Substitution::default(); - let err = compile_subst_flags(&lines, &mut chars, &mut subst).unwrap_err(); + let err = compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap_err(); assert!( err.to_string() .contains("multiple 'g' or numeric flags in substitute command") @@ -2090,7 +2100,7 @@ mod tests { let (lines, mut chars) = make_providers("2g"); let mut subst = Substitution::default(); - let err = compile_subst_flags(&lines, &mut chars, &mut subst).unwrap_err(); + let err = compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap_err(); assert!( err.to_string() .contains("multiple 'g' or numeric flags in substitute command") @@ -2102,7 +2112,7 @@ mod tests { let (lines, mut chars) = make_providers("w "); let mut subst = Substitution::default(); - let err = compile_subst_flags(&lines, &mut chars, &mut subst).unwrap_err(); + let err = compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap_err(); assert!(err.to_string().contains("missing file path")); } @@ -2113,7 +2123,7 @@ mod tests { let (lines, mut chars) = make_providers(&format!("w {}", out.display())); let mut subst = Substitution::default(); - compile_subst_flags(&lines, &mut chars, &mut subst).unwrap(); + compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap(); assert_eq!( subst.write_file.as_ref().map(|w| w.borrow().path.clone()), Some(out) @@ -2125,7 +2135,7 @@ mod tests { let (lines, mut chars) = make_providers("z"); let mut subst = Substitution::default(); - let err = compile_subst_flags(&lines, &mut chars, &mut subst).unwrap_err(); + let err = compile_subst_flags(&lines, &mut chars, &mut subst, &mut ctx()).unwrap_err(); assert!(err.to_string().contains("invalid substitute flag")); } diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index b31fed7..bbfee02 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -1303,3 +1303,13 @@ fn test_print_first_line_no_newline() { .succeeds() .stdout_is("foo"); } + +//--posix should reject GNU substitute flags i/I https://github.com/uutils/sed/issues/401 +#[test] +fn test_posix_reject_flags() { + new_ucmd!() + .args(&["--posix", "s/a/b/i"]) + .fails() + .code_is(1) + .stderr_is("sed: