From: Philip Hazelden Date: Sun, 3 Jul 2022 21:46:16 +0000 (+0100) Subject: Rename: fix empty 'from' with / in filename. X-Git-Tag: v2.39-rc1~584^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a6c0e598937aa26ab061214a08374a708249306;p=thirdparty%2Futil-linux.git Rename: fix empty 'from' with / in filename. Previously, if we did e.g. rename '' _ ./foo.txt it would try to rename to ._/foo.txt, because `string_replace` was passed `s="/foo.txt"` and `from` would match at the front. Now we pass `s="foo.txt"`. This doesn't affect the case when `to` contains a slash. In that situation we'll still place `to` at the very beginning of the path, e.g. rename '' _/ ./foo.txt # rename to _/./foo.txt rename '' /_ ./foo.txt # rename to /_./foo.txt --- diff --git a/misc-utils/rename.c b/misc-utils/rename.c index 9979ab1523..e47359c0d9 100644 --- a/misc-utils/rename.c +++ b/misc-utils/rename.c @@ -203,8 +203,13 @@ static int do_file(char *from, char *to, char *s, int verbose, int noact, warn(_("stat of %s failed"), s); return 2; } - if (strchr(from, '/') == NULL && strchr(to, '/') == NULL) + if (strchr(from, '/') == NULL && strchr(to, '/') == NULL) { file = strrchr(s, '/'); + /* We're going to search for `from` in `file`. If `from` is + empty, we don't want it to match before the '/'. */ + if (file != NULL) + file++; + } if (file == NULL) file = s; if (string_replace(from, to, file, s, &newname) != 0) diff --git a/tests/expected/rename/subdir b/tests/expected/rename/subdir index f429602762..684cdb8fa8 100644 --- a/tests/expected/rename/subdir +++ b/tests/expected/rename/subdir @@ -27,3 +27,8 @@ renxme/aa rename_path_a rename_path_b rename_path_b/test2 +== empty 'from' == +`rename_test' -> `_rename_test' +`./rename_test' -> `./_rename_test' +`rename_test' -> `rename_subdir/rename_test' +`./rename_test' -> `rename_subdir/./rename_test' diff --git a/tests/ts/rename/subdir b/tests/ts/rename/subdir index 192c2ff051..f6bd758756 100755 --- a/tests/ts/rename/subdir +++ b/tests/ts/rename/subdir @@ -65,4 +65,24 @@ rm -f rename_path_a/test2 rename_path_b/test2 rmdir rename_path_a rename_path_b +echo "== empty 'from' ==" >> $TS_OUTPUT + +touch rename_test +$TS_CMD_RENAME -v '' _ rename_test >> $TS_OUTPUT 2>> $TS_ERRLOG +rm -f *rename_test + +touch rename_test +$TS_CMD_RENAME -v '' _ ./rename_test >> $TS_OUTPUT 2>> $TS_ERRLOG +rm -f *rename_test + +touch rename_test +mkdir rename_subdir +$TS_CMD_RENAME -v '' rename_subdir/ rename_test >> $TS_OUTPUT 2>> $TS_ERRLOG +rm -rf rename_subdir + +touch rename_test +mkdir rename_subdir +$TS_CMD_RENAME -v '' rename_subdir/ ./rename_test >> $TS_OUTPUT 2>> $TS_ERRLOG +rm -rf rename_subdir + ts_finalize