From 9ffb00cd5117a71f71e51ec74f6fa9f3e78f3d57 Mon Sep 17 00:00:00 2001 From: Stefin Date: Sat, 20 Aug 2022 18:38:10 +0530 Subject: [PATCH 1/7] rm: added write-protected check for files Signed-off-by: Stefin --- src/uu/rm/src/rm.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index a55d3f2d163..32d50ee935d 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -14,6 +14,8 @@ use clap::{crate_version, Arg, Command}; use remove_dir_all::remove_dir_all; use std::collections::VecDeque; use std::fs; +use std::fs::File; +use std::io::ErrorKind; use std::io::{stderr, stdin, BufRead, Write}; use std::ops::BitOr; use std::path::{Path, PathBuf}; @@ -384,7 +386,7 @@ fn remove_file(path: &Path, options: &Options) -> bool { } else { true }; - if response { + if response && prompt_write_protected(path, false) { match fs::remove_file(path) { Ok(_) => { if options.verbose { @@ -406,6 +408,23 @@ fn remove_file(path: &Path, options: &Options) -> bool { false } +fn prompt_write_protected(path: &Path, is_dir: bool) -> bool { + match File::open(path) { + Ok(_) => true, + Err(err) => { + if err.kind() == ErrorKind::PermissionDenied { + if is_dir { + prompt(&(format!("rm: remove write-protected directory {}? ", path.quote()))) + } else { + prompt(&(format!("rm: remove write-protected file {}? ", path.quote()))) + } + } else { + true + } + } + } +} + fn prompt_file(path: &Path, is_dir: bool) -> bool { if is_dir { prompt(&(format!("rm: remove directory {}? ", path.quote()))) From a8326d7f3f92b7aac371d79a5fc00a22d19dcc3a Mon Sep 17 00:00:00 2001 From: Stefin Date: Tue, 23 Aug 2022 19:33:34 +0530 Subject: [PATCH 2/7] rm: added new InteractiveMode InteractiveMode::Never Signed-off-by: Stefin --- src/uu/rm/src/rm.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 32d50ee935d..96ab77431ff 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -29,6 +29,7 @@ enum InteractiveMode { Never, Once, Always, + Default, } struct Options { @@ -114,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } } else { - InteractiveMode::Never + InteractiveMode::Default } }, one_fs: matches.contains_id(OPT_ONE_FILE_SYSTEM), @@ -386,7 +387,7 @@ fn remove_file(path: &Path, options: &Options) -> bool { } else { true }; - if response && prompt_write_protected(path, false) { + if response && prompt_write_protected(path, false, options) { match fs::remove_file(path) { Ok(_) => { if options.verbose { @@ -408,7 +409,10 @@ fn remove_file(path: &Path, options: &Options) -> bool { false } -fn prompt_write_protected(path: &Path, is_dir: bool) -> bool { +fn prompt_write_protected(path: &Path, is_dir: bool, options: &Options) -> bool { + if options.interactive == InteractiveMode::Never { + return true; + } match File::open(path) { Ok(_) => true, Err(err) => { From ad4eac867f4cd560ec8eee1d4beb409ab64e48a8 Mon Sep 17 00:00:00 2001 From: Stefin Date: Tue, 23 Aug 2022 21:17:48 +0530 Subject: [PATCH 3/7] rm: added test for rm_prompt_write_protected Signed-off-by: Stefin --- tests/by-util/test_rm.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index e765935768e..c752cc442f3 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -363,3 +363,33 @@ fn test_rm_directory_rights_rm1() { assert!(!at.dir_exists("b/c")); assert!(!at.dir_exists("b/d")); } + +#[test] +fn test_prompt_write_protected_yes() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + let file_1 = "test_rm_prompt_write_protected_1"; + + at.touch(file_1); + + #[cfg(feature = "chmod")] + scene.ccmd("chmod").arg("0").arg(file_1).succeeds(); + + scene.ucmd().arg(file_1).pipe_in("y").succeeds(); + assert!(!at.file_exists(file_1)); +} + +#[test] +fn test_prompt_write_protected_no() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + let file_2 = "test_rm_prompt_write_protected_2"; + + at.touch(file_2); + + #[cfg(feature = "chmod")] + scene.ccmd("chmod").arg("0").arg(file_2).succeeds(); + + scene.ucmd().arg(file_2).pipe_in("n").succeeds(); + assert!(at.file_exists(file_2)); +} From 4c1c9ebf89eac19fb3b807da66fd0cdd941dbf47 Mon Sep 17 00:00:00 2001 From: Stefin Date: Sat, 27 Aug 2022 19:38:10 +0530 Subject: [PATCH 4/7] rm: change InteractiveMode::Default to InteractiveMode::PromptProtected Signed-off-by: Stefin --- src/uu/rm/src/rm.rs | 4 ++-- tests/by-util/test_rm.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 96ab77431ff..80f1c8cd9bb 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -29,7 +29,7 @@ enum InteractiveMode { Never, Once, Always, - Default, + PromptProtected, } struct Options { @@ -115,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } } else { - InteractiveMode::Default + InteractiveMode::PromptProtected } }, one_fs: matches.contains_id(OPT_ONE_FILE_SYSTEM), diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index c752cc442f3..c5c1503719b 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -364,6 +364,7 @@ fn test_rm_directory_rights_rm1() { assert!(!at.dir_exists("b/d")); } +#[cfg(feature = "chmod")] #[test] fn test_prompt_write_protected_yes() { let scene = TestScenario::new(util_name!()); @@ -372,13 +373,13 @@ fn test_prompt_write_protected_yes() { at.touch(file_1); - #[cfg(feature = "chmod")] scene.ccmd("chmod").arg("0").arg(file_1).succeeds(); scene.ucmd().arg(file_1).pipe_in("y").succeeds(); assert!(!at.file_exists(file_1)); } +#[cfg(feature = "chmod")] #[test] fn test_prompt_write_protected_no() { let scene = TestScenario::new(util_name!()); @@ -387,7 +388,6 @@ fn test_prompt_write_protected_no() { at.touch(file_2); - #[cfg(feature = "chmod")] scene.ccmd("chmod").arg("0").arg(file_2).succeeds(); scene.ucmd().arg(file_2).pipe_in("n").succeeds(); From 4f967de2ebede37d073d35a996b8637f0d9d1195 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 06:41:02 +0000 Subject: [PATCH 5/7] build(deps): bump vmactions/freebsd-vm from 0.2.3 to 0.2.4 Bumps [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) from 0.2.3 to 0.2.4. - [Release notes](https://github.com/vmactions/freebsd-vm/releases) - [Commits](https://github.com/vmactions/freebsd-vm/compare/v0.2.3...v0.2.4) --- updated-dependencies: - dependency-name: vmactions/freebsd-vm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/CICD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 2e34c0fe848..11439344ceb 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -921,7 +921,7 @@ jobs: - uses: Swatinem/rust-cache@v1 - name: Prepare, build and test ## spell-checker:ignore (ToDO) sshfs usesh vmactions - uses: vmactions/freebsd-vm@v0.2.3 + uses: vmactions/freebsd-vm@v0.2.4 with: usesh: true # sync: sshfs From a9b5d9dccfbc8877a636f85ccad929a0a02a1b15 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 29 Aug 2022 10:44:52 +0200 Subject: [PATCH 6/7] Replace forbid_empty_values() with value_parser() --- src/uu/realpath/src/realpath.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uu/realpath/src/realpath.rs b/src/uu/realpath/src/realpath.rs index ea5d7f795e9..c65cf737410 100644 --- a/src/uu/realpath/src/realpath.rs +++ b/src/uu/realpath/src/realpath.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{crate_version, Arg, ArgMatches, Command}; +use clap::{builder::NonEmptyStringValueParser, crate_version, Arg, ArgMatches, Command}; use std::{ io::{stdout, Write}, path::{Path, PathBuf}, @@ -150,7 +150,7 @@ pub fn uu_app<'a>() -> Command<'a> { .long(OPT_RELATIVE_TO) .takes_value(true) .value_name("DIR") - .forbid_empty_values(true) + .value_parser(NonEmptyStringValueParser::new()) .help("print the resolved path relative to DIR"), ) .arg( @@ -158,14 +158,14 @@ pub fn uu_app<'a>() -> Command<'a> { .long(OPT_RELATIVE_BASE) .takes_value(true) .value_name("DIR") - .forbid_empty_values(true) + .value_parser(NonEmptyStringValueParser::new()) .help("print absolute paths unless paths below DIR"), ) .arg( Arg::new(ARG_FILES) .multiple_occurrences(true) .required(true) - .forbid_empty_values(true) + .value_parser(NonEmptyStringValueParser::new()) .value_hint(clap::ValueHint::AnyPath), ) } From a33bc185a5076ea5f6b478ec08b2a806773afb57 Mon Sep 17 00:00:00 2001 From: Stefin Date: Mon, 29 Aug 2022 18:09:02 +0530 Subject: [PATCH 7/7] rm: added check for write protected regular empty file Signed-off-by: Stefin --- src/uu/rm/src/rm.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 80f1c8cd9bb..571a6d2c053 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -420,7 +420,15 @@ fn prompt_write_protected(path: &Path, is_dir: bool, options: &Options) -> bool if is_dir { prompt(&(format!("rm: remove write-protected directory {}? ", path.quote()))) } else { - prompt(&(format!("rm: remove write-protected file {}? ", path.quote()))) + if fs::metadata(path).unwrap().len() == 0 { + return prompt( + &(format!( + "rm: remove write-protected regular empty file {}? ", + path.quote() + )), + ); + } + prompt(&(format!("rm: remove write-protected regular file {}? ", path.quote()))) } } else { true