Serenity Operating System
1/*
2 * Copyright (c) 2021, Xavier Defrang <xavier.defrang@gmail.com>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibCore/FilePermissionsMask.h>
8#include <LibTest/TestCase.h>
9
10TEST_CASE(file_permission_mask_from_symbolic_notation)
11{
12 auto mask = Core::FilePermissionsMask::from_symbolic_notation(""sv);
13 EXPECT(!mask.is_error());
14 EXPECT_EQ(mask.value().clear_mask(), 0);
15 EXPECT_EQ(mask.value().write_mask(), 0);
16 EXPECT_EQ(mask.value().apply(0), 0);
17 EXPECT_EQ(mask.value().apply(0664), 0664);
18
19 mask = Core::FilePermissionsMask::from_symbolic_notation("u+rwx"sv);
20 EXPECT(!mask.is_error());
21 EXPECT_EQ(mask.value().clear_mask(), 0);
22 EXPECT_EQ(mask.value().write_mask(), 0700);
23 EXPECT_EQ(mask.value().apply(0), 0700);
24 EXPECT_EQ(mask.value().apply(0664), 0764);
25
26 mask = Core::FilePermissionsMask::from_symbolic_notation("g+rwx"sv);
27 EXPECT(!mask.is_error());
28 EXPECT_EQ(mask.value().clear_mask(), 0);
29 EXPECT_EQ(mask.value().write_mask(), 0070);
30 EXPECT_EQ(mask.value().apply(0), 0070);
31 EXPECT_EQ(mask.value().apply(0664), 0674);
32
33 mask = Core::FilePermissionsMask::from_symbolic_notation("o+rwx"sv);
34 EXPECT(!mask.is_error());
35 EXPECT_EQ(mask.value().clear_mask(), 0);
36 EXPECT_EQ(mask.value().write_mask(), 0007);
37 EXPECT_EQ(mask.value().apply(0), 0007);
38 EXPECT_EQ(mask.value().apply(0664), 0667);
39
40 mask = Core::FilePermissionsMask::from_symbolic_notation("a=rx"sv);
41 EXPECT(!mask.is_error());
42 EXPECT_EQ(mask.value().clear_mask(), 0777);
43 EXPECT_EQ(mask.value().write_mask(), 0555);
44 EXPECT_EQ(mask.value().apply(0), 0555);
45 EXPECT_EQ(mask.value().apply(0664), 0555);
46
47 mask = Core::FilePermissionsMask::from_symbolic_notation("ugo=rx"sv);
48 EXPECT(!mask.is_error());
49 EXPECT_EQ(mask.value().clear_mask(), 0777);
50 EXPECT_EQ(mask.value().write_mask(), 0555);
51 EXPECT_EQ(mask.value().apply(0), 0555);
52 EXPECT_EQ(mask.value().apply(0664), 0555);
53
54 mask = Core::FilePermissionsMask::from_symbolic_notation("u+rw,g=rx,o-rwx"sv);
55 EXPECT(!mask.is_error());
56 EXPECT_EQ(mask.value().clear_mask(), 0077);
57 EXPECT_EQ(mask.value().write_mask(), 0650);
58 EXPECT_EQ(mask.value().apply(0), 0650);
59 EXPECT_EQ(mask.value().apply(0177), 0750);
60
61 mask = Core::FilePermissionsMask::from_symbolic_notation("+r"sv);
62 EXPECT(!mask.is_error());
63 EXPECT_EQ(mask.value().clear_mask(), 0);
64 EXPECT_EQ(mask.value().write_mask(), 0444);
65 EXPECT_EQ(mask.value().apply(0), 0444);
66 EXPECT_EQ(mask.value().apply(0123), 0567);
67
68 mask = Core::FilePermissionsMask::from_symbolic_notation("=rx"sv);
69 EXPECT(!mask.is_error());
70 EXPECT_EQ(mask.value().clear_mask(), 0777);
71 EXPECT_EQ(mask.value().write_mask(), 0555);
72 EXPECT_EQ(mask.value().apply(0), 0555);
73 EXPECT_EQ(mask.value().apply(0664), 0555);
74
75 mask = Core::FilePermissionsMask::from_symbolic_notation("a+X"sv);
76 EXPECT(!mask.is_error());
77 EXPECT_EQ(mask.value().clear_mask(), 0);
78 EXPECT_EQ(mask.value().write_mask(), 0);
79 EXPECT_EQ(mask.value().directory_or_executable_mask().clear_mask(), 0);
80 EXPECT_EQ(mask.value().directory_or_executable_mask().write_mask(), 0111);
81 EXPECT_EQ(mask.value().apply(0), 0);
82 EXPECT_EQ(mask.value().apply(0100), 0111);
83 EXPECT_EQ(mask.value().apply(S_IFDIR | 0), S_IFDIR | 0111);
84
85 mask = Core::FilePermissionsMask::from_symbolic_notation("z+rw"sv);
86 EXPECT(mask.is_error());
87 EXPECT(mask.error().string_literal().starts_with("invalid class"sv));
88
89 mask = Core::FilePermissionsMask::from_symbolic_notation("u*rw"sv);
90 EXPECT(mask.is_error());
91 EXPECT(mask.error().string_literal().starts_with("invalid operation"sv));
92
93 mask = Core::FilePermissionsMask::from_symbolic_notation("u+rz"sv);
94 EXPECT(mask.is_error());
95 EXPECT(mask.error().string_literal().starts_with("invalid symbolic permission"sv));
96
97 mask = Core::FilePermissionsMask::from_symbolic_notation("u+rw;g+rw"sv);
98 EXPECT(mask.is_error());
99 EXPECT(mask.error().string_literal().starts_with("invalid symbolic permission"sv));
100}
101
102TEST_CASE(file_permission_mask_parse)
103{
104 auto numeric_mask = Core::FilePermissionsMask::parse("750"sv);
105 auto symbolic_mask = Core::FilePermissionsMask::parse("u=rwx,g=rx,o-rwx"sv);
106
107 EXPECT_EQ(numeric_mask.value().apply(0), 0750);
108 EXPECT_EQ(symbolic_mask.value().apply(0), 0750);
109
110 EXPECT_EQ(numeric_mask.value().clear_mask(), symbolic_mask.value().clear_mask());
111 EXPECT_EQ(numeric_mask.value().write_mask(), symbolic_mask.value().write_mask());
112
113 auto mask = Core::FilePermissionsMask::parse("888"sv);
114 EXPECT(mask.is_error());
115
116 mask = Core::FilePermissionsMask::parse("z+rw"sv);
117 EXPECT(mask.is_error());
118}
119
120TEST_CASE(numeric_mask_special_bits)
121{
122 {
123 auto mask = Core::FilePermissionsMask::parse("750"sv);
124 EXPECT(!mask.is_error());
125 EXPECT_EQ(mask.value().apply(07000), 07750);
126 }
127
128 {
129 auto mask = Core::FilePermissionsMask::parse("7750"sv);
130 EXPECT(!mask.is_error());
131 EXPECT_EQ(mask.value().apply(0), 07750);
132 }
133
134 {
135 auto mask = Core::FilePermissionsMask::parse("0750"sv);
136 EXPECT(!mask.is_error());
137 EXPECT_EQ(mask.value().apply(07000), 0750);
138 }
139}