From 05beda493cf176e8d689e9c5eaf4273a32be772f Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 15 Jun 2017 20:14:22 -0400 Subject: -perm: Handle permcopy (e.g. u=rw,g=u) correctly --- parse.c | 21 ++++++++++++++++----- tests.sh | 5 +++++ tests/test_permcopy.out | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 tests/test_permcopy.out diff --git a/parse.c b/parse.c index ed7685b..4a01467 100644 --- a/parse.c +++ b/parse.c @@ -1507,21 +1507,32 @@ static int parse_mode(const struct parser_state *state, const char *mode, struct break; case MODE_OP: - file_change = 0; - dir_change = 0; - switch (*i) { case 'u': + file_change = (expr->file_mode >> 6) & 07; + dir_change = (expr->dir_mode >> 6) & 07; + break; case 'g': + file_change = (expr->file_mode >> 3) & 07; + dir_change = (expr->dir_mode >> 3) & 07; + break; case 'o': - // PERMCOPY (e.g. u=g) has no effect for -perm - mstate = MODE_ACTION_APPLY; + file_change = expr->file_mode & 07; + dir_change = expr->dir_mode & 07; break; default: + file_change = 0; + dir_change = 0; mstate = MODE_PERM; continue; } + + file_change |= (file_change << 6) | (file_change << 3); + file_change &= who; + dir_change |= (dir_change << 6) | (dir_change << 3); + dir_change &= who; + mstate = MODE_ACTION_APPLY; break; case MODE_PERM: diff --git a/tests.sh b/tests.sh index c518f33..2fce23b 100755 --- a/tests.sh +++ b/tests.sh @@ -164,6 +164,7 @@ posix_tests=( test_perm_symbolic test_perm_symbolic_minus test_perm_leading_plus_symbolic_minus + test_permcopy test_ok_stdin test_parens test_bang @@ -833,6 +834,10 @@ function test_perm_octal_plus() { ! $BFS perms -perm +777 2>/dev/null } +function test_permcopy() { + bfs_diff perms -perm u+rw,g+u-w,o=g +} + function test_ok_stdin() { # -ok should *not* close stdin # See https://savannah.gnu.org/bugs/?24561 diff --git a/tests/test_permcopy.out b/tests/test_permcopy.out new file mode 100644 index 0000000..4e64e49 --- /dev/null +++ b/tests/test_permcopy.out @@ -0,0 +1 @@ +perms/rw -- cgit v1.2.3