From 12a6ec929297fb7dc699c6093b508a402e1ded04 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Boric Date: Fri, 21 Jan 2022 19:32:35 +0100 Subject: [PATCH] LibCore: Parse classless symbolic notation --- .../Libraries/LibCore/FilePermissionsMask.cpp | 59 +++++++++++-------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/Userland/Libraries/LibCore/FilePermissionsMask.cpp b/Userland/Libraries/LibCore/FilePermissionsMask.cpp index 1b6cdfc164..92f632e72f 100644 --- a/Userland/Libraries/LibCore/FilePermissionsMask.cpp +++ b/Userland/Libraries/LibCore/FilePermissionsMask.cpp @@ -13,7 +13,8 @@ namespace Core { enum State { - Reference, + Classes, + Operation, Mode }; @@ -48,47 +49,59 @@ ErrorOr FilePermissionsMask::from_symbolic_notation(StringV { auto mask = FilePermissionsMask(); - u8 state = State::Reference; + u8 state = State::Classes; u8 classes = 0; u8 operation = 0; for (auto ch : string) { switch (state) { - case State::Reference: { + case State::Classes: { // one or more [ugoa] terminated by one operator [+-=] - if (ch == 'u') + if (ch == 'u') { classes |= ClassFlag::User; - else if (ch == 'g') + state = State::Operation; + break; + } else if (ch == 'g') { classes |= ClassFlag::Group; - else if (ch == 'o') + state = State::Operation; + break; + } else if (ch == 'o') { classes |= ClassFlag::Other; - else if (ch == 'a') + state = State::Operation; + break; + } else if (ch == 'a') { classes = ClassFlag::User | ClassFlag::Group | ClassFlag::Other; - else { - if (classes == 0) - return Error::from_string_literal("invalid access class: expected 'u', 'g', 'o' or 'a' "sv); - - 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); - - state = State::Mode; + state = State::Operation; + break; } + } + [[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; } case State::Mode: { // one or more [rwx] terminated by a comma - // End of mode part, expect reference next + // End of mode part, expect class next if (ch == ',') { - state = State::Reference; + state = State::Classes; classes = operation = 0; continue; }