diff --git a/Tests/LibCore/TestLibCoreFilePermissionsMask.cpp b/Tests/LibCore/TestLibCoreFilePermissionsMask.cpp index 544bd750a0..20f1e9899e 100644 --- a/Tests/LibCore/TestLibCoreFilePermissionsMask.cpp +++ b/Tests/LibCore/TestLibCoreFilePermissionsMask.cpp @@ -44,6 +44,13 @@ TEST_CASE(file_permission_mask_from_symbolic_notation) EXPECT_EQ(mask.value().apply(0), 0555); EXPECT_EQ(mask.value().apply(0664), 0555); + mask = Core::FilePermissionsMask::from_symbolic_notation("ugo=rx"sv); + EXPECT(!mask.is_error()); + EXPECT_EQ(mask.value().clear_mask(), 0777); + EXPECT_EQ(mask.value().write_mask(), 0555); + EXPECT_EQ(mask.value().apply(0), 0555); + EXPECT_EQ(mask.value().apply(0664), 0555); + mask = Core::FilePermissionsMask::from_symbolic_notation("u+rw,g=rx,o-rwx"sv); EXPECT(!mask.is_error()); EXPECT_EQ(mask.value().clear_mask(), 0077); @@ -51,6 +58,20 @@ TEST_CASE(file_permission_mask_from_symbolic_notation) EXPECT_EQ(mask.value().apply(0), 0650); EXPECT_EQ(mask.value().apply(0177), 0750); + mask = Core::FilePermissionsMask::from_symbolic_notation("+r"sv); + EXPECT(!mask.is_error()); + EXPECT_EQ(mask.value().clear_mask(), 0); + EXPECT_EQ(mask.value().write_mask(), 0444); + EXPECT_EQ(mask.value().apply(0), 0444); + EXPECT_EQ(mask.value().apply(0123), 0567); + + mask = Core::FilePermissionsMask::from_symbolic_notation("=rx"sv); + EXPECT(!mask.is_error()); + EXPECT_EQ(mask.value().clear_mask(), 0777); + EXPECT_EQ(mask.value().write_mask(), 0555); + EXPECT_EQ(mask.value().apply(0), 0555); + EXPECT_EQ(mask.value().apply(0664), 0555); + mask = Core::FilePermissionsMask::from_symbolic_notation("z+rw"sv); EXPECT(mask.is_error()); diff --git a/Userland/Libraries/LibCore/FilePermissionsMask.cpp b/Userland/Libraries/LibCore/FilePermissionsMask.cpp index 92f632e72f..fe759725a5 100644 --- a/Userland/Libraries/LibCore/FilePermissionsMask.cpp +++ b/Userland/Libraries/LibCore/FilePermissionsMask.cpp @@ -14,14 +14,14 @@ namespace Core { enum State { Classes, - Operation, Mode }; enum ClassFlag { Other = 1, Group = 2, - User = 4 + User = 4, + All = 7 }; enum Operation { @@ -56,43 +56,32 @@ ErrorOr FilePermissionsMask::from_symbolic_notation(StringV for (auto ch : string) { switch (state) { case State::Classes: { - // one or more [ugoa] terminated by one operator [+-=] - if (ch == 'u') { + // zero or more [ugoa] terminated by one operator [+-=] + if (ch == 'u') classes |= ClassFlag::User; - state = State::Operation; - break; - } else if (ch == 'g') { + else if (ch == 'g') classes |= ClassFlag::Group; - state = State::Operation; - break; - } else if (ch == 'o') { + else if (ch == 'o') classes |= ClassFlag::Other; - state = State::Operation; - break; - } else if (ch == 'a') { - classes = ClassFlag::User | ClassFlag::Group | ClassFlag::Other; - state = State::Operation; - break; + else if (ch == 'a') + classes = ClassFlag::All; + else { + if (ch == '+') + operation = Operation::Add; + else if (ch == '-') + operation = Operation::Remove; + else if (ch == '=') + operation = Operation::Assign; + else + return Error::from_string_literal("invalid operation: expected '+', '-' or '='"sv); + + // if an operation was specified without a class, assume all + if (classes == 0) + classes = ClassFlag::All; + + state = State::Mode; } - } - [[fallthrough]]; - case State::Operation: { - if (ch == '+') - operation = Operation::Add; - else if (ch == '-') - operation = Operation::Remove; - else if (ch == '=') - operation = Operation::Assign; - else if (classes == 0) - return Error::from_string_literal("invalid access class: expected 'u', 'g', 'o' or 'a' "sv); - else - return Error::from_string_literal("invalid operation: expected '+', '-' or '='"sv); - // if an operation was specified without a class, assume all - if (classes == 0) - classes = ClassFlag::User | ClassFlag::Group | ClassFlag::Other; - - state = State::Mode; break; }