@@ -71,6 +71,54 @@ int main(int argc, char **argv)
7171 (void )argc ;
7272 (void )argv ;
7373 assert (qubes_pure_validate_file_name ((uint8_t * )u8"simple_safe_filename.txt" ));
74+
75+ // Directory traversal checks
76+ assert (!qubes_pure_validate_file_name ((uint8_t * )".." ));
77+ assert (!qubes_pure_validate_file_name ((uint8_t * )"../.." ));
78+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a/.." ));
79+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a/../b" ));
80+ assert (!qubes_pure_validate_file_name ((uint8_t * )"/" ));
81+ assert (!qubes_pure_validate_file_name ((uint8_t * )"//" ));
82+ assert (!qubes_pure_validate_file_name ((uint8_t * )"///" ));
83+ assert (!qubes_pure_validate_file_name ((uint8_t * )"/a" ));
84+ assert (!qubes_pure_validate_file_name ((uint8_t * )"//a" ));
85+ assert (!qubes_pure_validate_file_name ((uint8_t * )"///a" ));
86+
87+ // No repeated slashes
88+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a//b" ));
89+
90+ // No "." as a path component
91+ assert (!qubes_pure_validate_file_name ((uint8_t * )"." ));
92+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a/." ));
93+ assert (!qubes_pure_validate_file_name ((uint8_t * )"./a" ));
94+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a/./a" ));
95+
96+ // No ".." as a path component
97+ assert (!qubes_pure_validate_file_name ((uint8_t * )".." ));
98+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a/.." ));
99+ assert (!qubes_pure_validate_file_name ((uint8_t * )"../a" ));
100+ assert (!qubes_pure_validate_file_name ((uint8_t * )"a/../a" ));
101+
102+ // Looks like "." or ".." but is not
103+ assert (qubes_pure_validate_file_name ((const uint8_t * )".a" ));
104+ assert (qubes_pure_validate_file_name ((const uint8_t * )"..a" ));
105+
106+ // Symbolic links
107+ // Top level cannot be symlink
108+ assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a" , (const uint8_t * )"b" ));
109+ // Symbolic links cannot escape
110+ assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b" , (const uint8_t * )"../a" ));
111+ assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b" , (const uint8_t * )"../a/b/c" ));
112+ assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"../../a" ));
113+ assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b" , (const uint8_t * )"a" ));
114+ assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"../a" ));
115+ // Absolute symlinks are rejected
116+ assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"/a" ));
117+ // Symlinks may end in "..".
118+ assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )".." ));
119+ // Symlinks may end in "/".
120+ assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"a/" ));
121+
74122 // Greek letters are safe
75123 assert (qubes_pure_validate_file_name ((uint8_t * )u8"\u03b2.txt" ));
76124 assert (qubes_pure_validate_file_name ((uint8_t * )u8"\u03b1.txt" ));
@@ -174,51 +222,4 @@ int main(int argc, char **argv)
174222 assert (j < 0x10FFFFE );
175223 }
176224 }
177-
178- // Directory traversal checks
179- assert (!qubes_pure_validate_file_name ((uint8_t * )".." ));
180- assert (!qubes_pure_validate_file_name ((uint8_t * )"../.." ));
181- assert (!qubes_pure_validate_file_name ((uint8_t * )"a/.." ));
182- assert (!qubes_pure_validate_file_name ((uint8_t * )"a/../b" ));
183- assert (!qubes_pure_validate_file_name ((uint8_t * )"/" ));
184- assert (!qubes_pure_validate_file_name ((uint8_t * )"//" ));
185- assert (!qubes_pure_validate_file_name ((uint8_t * )"///" ));
186- assert (!qubes_pure_validate_file_name ((uint8_t * )"/a" ));
187- assert (!qubes_pure_validate_file_name ((uint8_t * )"//a" ));
188- assert (!qubes_pure_validate_file_name ((uint8_t * )"///a" ));
189-
190- // No repeated slashes
191- assert (!qubes_pure_validate_file_name ((uint8_t * )"a//b" ));
192-
193- // No "." as a path component
194- assert (!qubes_pure_validate_file_name ((uint8_t * )"." ));
195- assert (!qubes_pure_validate_file_name ((uint8_t * )"a/." ));
196- assert (!qubes_pure_validate_file_name ((uint8_t * )"./a" ));
197- assert (!qubes_pure_validate_file_name ((uint8_t * )"a/./a" ));
198-
199- // No ".." as a path component
200- assert (!qubes_pure_validate_file_name ((uint8_t * )".." ));
201- assert (!qubes_pure_validate_file_name ((uint8_t * )"a/.." ));
202- assert (!qubes_pure_validate_file_name ((uint8_t * )"../a" ));
203- assert (!qubes_pure_validate_file_name ((uint8_t * )"a/../a" ));
204-
205- // Looks like "." or ".." but is not
206- assert (qubes_pure_validate_file_name ((const uint8_t * )".a" ));
207- assert (qubes_pure_validate_file_name ((const uint8_t * )"..a" ));
208-
209- // Symbolic links
210- // Top level cannot be symlink
211- assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a" , (const uint8_t * )"b" ));
212- // Symbolic links cannot escape
213- assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b" , (const uint8_t * )"../a" ));
214- assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b" , (const uint8_t * )"../a/b/c" ));
215- assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"../../a" ));
216- assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b" , (const uint8_t * )"a" ));
217- assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"../a" ));
218- // Absolute symlinks are rejected
219- assert (!qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"/a" ));
220- // Symlinks may end in "..".
221- assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )".." ));
222- // Symlinks may end in "/".
223- assert (qubes_pure_validate_symbolic_link ((const uint8_t * )"a/b/c" , (const uint8_t * )"a/" ));
224225}
0 commit comments