From cff7833bf65a1759ca9a4134bf8e4227c48ef979 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Wed, 1 Jun 2022 09:35:31 -0400 Subject: [PATCH 1/2] mktemp: only replace last contiguous block of Xs Fix a bug in which `mktemp` would replace everything in the template argument from the first 'X' to the last 'X' with random bytes, instead of just replacing the last contiguous block of 'X's. Before this commit, $ mktemp XXX_XXX 2meCpfM After this commit, $ mktemp XXX_XXX XXX_Rp5 This fixes test cases `suffix2f` and `suffix2d` in `tests/misc/mktemp.pl` in the GNU coreutils test suite. --- src/uu/mktemp/src/mktemp.rs | 40 +++++++++++++++++++++++++++++++++--- tests/by-util/test_mktemp.rs | 22 ++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index dd1f57b8b44..e3f81199d4f 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -205,12 +205,29 @@ struct Params { suffix: String, } +/// Find the start and end indices of the last contiguous block of Xs. +/// +/// If no contiguous block of at least three Xs could be found, this +/// function returns `None`. +/// +/// # Examples +/// +/// ```rust,ignore +/// assert_eq!(find_last_contiguous_block_of_xs("XXX_XXX"), Some((4, 7))); +/// assert_eq!(find_last_contiguous_block_of_xs("aXbXcX"), None); +/// ``` +fn find_last_contiguous_block_of_xs(s: &str) -> Option<(usize, usize)> { + let j = s.rfind("XXX")? + 3; + let i = s[..j].rfind(|c| c != 'X').map_or(0, |i| i + 1); + Some((i, j)) +} + impl Params { fn from(options: Options) -> Result { // Get the start and end indices of the randomized part of the template. // // For example, if the template is "abcXXXXyz", then `i` is 3 and `j` is 7. - let i = match options.template.find("XXX") { + let (i, j) = match find_last_contiguous_block_of_xs(&options.template) { None => { let s = match options.suffix { None => options.template, @@ -218,9 +235,8 @@ impl Params { }; return Err(MkTempError::TooFewXs(s)); } - Some(i) => i, + Some(indices) => indices, }; - let j = options.template.rfind("XXX").unwrap() + 3; // Combine the directory given as an option and the prefix of the template. // @@ -450,3 +466,21 @@ fn exec(dir: &str, prefix: &str, rand: usize, suffix: &str, make_dir: bool) -> U println_verbatim(path).map_err_context(|| "failed to print directory name".to_owned()) } + +#[cfg(test)] +mod tests { + use crate::find_last_contiguous_block_of_xs as findxs; + + #[test] + fn test_find_last_contiguous_block_of_xs() { + assert_eq!(findxs("XXX"), Some((0, 3))); + assert_eq!(findxs("XXX_XXX"), Some((4, 7))); + assert_eq!(findxs("XXX_XXX_XXX"), Some((8, 11))); + assert_eq!(findxs("aaXXXbb"), Some((2, 5))); + assert_eq!(findxs(""), None); + assert_eq!(findxs("X"), None); + assert_eq!(findxs("XX"), None); + assert_eq!(findxs("aXbXcX"), None); + assert_eq!(findxs("aXXbXXcXX"), None); + } +} diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 55ca021c105..2dbcc9f7f9c 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -572,3 +572,25 @@ fn test_too_few_xs_suffix_directory() { fn test_too_many_arguments() { new_ucmd!().args(&["-q", "a", "b"]).fails().code_is(1); } + +#[test] +fn test_two_contiguous_wildcard_blocks() { + let (at, mut ucmd) = at_and_ucmd!(); + let template = "XXX_XXX"; + let result = ucmd.arg(template).succeeds(); + let filename = result.no_stderr().stdout_str().trim_end(); + assert_eq!(&filename[..4], "XXX_"); + assert_matches_template!(template, filename); + assert!(at.file_exists(filename)); +} + +#[test] +fn test_three_contiguous_wildcard_blocks() { + let (at, mut ucmd) = at_and_ucmd!(); + let template = "XXX_XXX_XXX"; + let result = ucmd.arg(template).succeeds(); + let filename = result.no_stderr().stdout_str().trim_end(); + assert_eq!(&filename[..8], "XXX_XXX_"); + assert_matches_template!(template, filename); + assert!(at.file_exists(filename)); +} From c8748022854904833a65939e4860a7eeed10fc42 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 5 Jun 2022 09:32:24 +0200 Subject: [PATCH 2/2] Add a word to the spell ignore list --- src/uu/mktemp/src/mktemp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index e3f81199d4f..78e36874ea6 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -6,7 +6,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (paths) GPGHome +// spell-checker:ignore (paths) GPGHome findxs use clap::{crate_version, Arg, ArgMatches, Command}; use uucore::display::{println_verbatim, Quotable};