2 // MonoTests.System.Security.Permissions.FileIOPermissionTest.cs
5 // Nick Drochak (ndrochak@gol.com)
7 // (C) 2001-2002 Nick Drochak II
9 // Note: Only Unix and Windows file paths are tested. To run the tests on Mac OS's
10 // search for the "FIXME" notes below and adjust accordingly.
14 using System.Runtime.InteropServices;
15 using System.Reflection;
16 using System.Security;
17 using System.Security.Permissions;
20 using NUnit.Framework;
22 namespace MonoTests.System.Security.Permissions {
24 public class FilePathUtil {
25 [DllImport("kernel32.dll")]
26 private static extern uint GetLongPathName (string shortPath,
27 StringBuilder buffer, uint bufLength);
29 static public string GetLongPathName (string somePath)
31 StringBuilder buffer = new StringBuilder(260);
32 if (0 != GetLongPathName (somePath, buffer, (uint) buffer.Capacity))
33 return buffer.ToString ();
38 [DllImport("kernel32.dll", SetLastError=true)]
39 private static extern uint GetShortPathName ( string longPath,
40 StringBuilder buffer, uint bufLength);
42 static public string GetShortPathName (string somePath)
44 StringBuilder buffer = new StringBuilder(260);
45 if (0 != GetShortPathName (somePath, buffer, (uint) buffer.Capacity))
46 return buffer.ToString ();
54 public class FileIOPermissionTest {
56 string[] pathArrayGood;
57 string[] pathArrayBad;
60 string[] pathsInPermission;
61 string[] pathArrayGood2;
62 FileIOPermission unrestricted;
64 private string filename;
70 Environment.CurrentDirectory = Path.GetTempPath();
71 filename = Path.GetTempFileName ();
73 int os = (int) Environment.OSVersion.Platform;
74 unix = ((os == 4) || (os == 128) || (os == 6));
77 pathsInPermission = null;
78 pathArrayGood = new string[2];
79 pathArrayBad = new string[2];
80 pathArrayGood2 = new string[3];
81 // FIXME: Adjust to run on Mac OS's
82 if (Path.VolumeSeparatorChar == ':') {
83 pathArrayGood[0] = "c:\\temp1";
84 pathArrayGood[1] = "d:\\temp2";
85 pathArrayBad[0] = "c:\\temp1";
86 pathArrayBad[1] = "d:\\temp*";
87 pathArrayGood2[0] = "c:\\temp1";
88 pathArrayGood2[1] = "d:\\temp2";
89 pathArrayGood2[2] = "z:\\something";
92 pathArrayGood[0] = "/temp1";
93 pathArrayGood[1] = "/usr/temp2";
94 pathArrayBad[0] = "/temp1";
95 pathArrayBad[1] = "/usr/temp*"; // not really bad under Unix...
96 pathArrayGood2[0] = "/temp1";
97 pathArrayGood2[1] = "/usr/temp2";
98 pathArrayGood2[2] = "/usr/bin/something";
103 public void TearDown ()
105 if (File.Exists (filename))
106 File.Delete (filename);
110 public void ConstructorPermissionState ()
112 p = new FileIOPermission(PermissionState.None);
113 Assert.AreEqual(false, p.IsUnrestricted(), "Should be Restricted");
114 p = new FileIOPermission(PermissionState.Unrestricted);
115 Assert.AreEqual(true, p.IsUnrestricted(), "Should be Unrestricted");
117 p = new FileIOPermission((PermissionState)77);
118 Assert.Fail("Should have thrown an exception on invalid PermissionState");
121 // we should be here if things are working. nothing to do
126 [ExpectedException (typeof (ArgumentNullException))]
127 public void ConstructorString_Null ()
129 p = new FileIOPermission(FileIOPermissionAccess.Append, (string)null);
133 [ExpectedException (typeof (ArgumentException))]
134 public void ConstructorString_NotRooted ()
136 p = new FileIOPermission(FileIOPermissionAccess.Append, "this path is not rooted");
140 [ExpectedException (typeof (ArgumentException))]
141 public void ConstructorString_InvalidPath ()
143 p = new FileIOPermission(FileIOPermissionAccess.Append, "<this is not a valid path>");
147 public void ConstructorString_Wildcard ()
150 // note: this is a valid path on UNIX so we must be able to protect it
151 p = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayBad [1]);
153 catch (ArgumentException) {
155 Assert.Fail ("Wildcard * is valid in filenames");
156 // else it's normal for Windows to throw ArgumentException
158 catch (Exception e) {
159 Assert.Fail ("Bad or wrong exception: " + e.ToString ());
164 [ExpectedException (typeof (ArgumentException))]
165 public void ConstructorString_InvalidAccess ()
167 p = new FileIOPermission((FileIOPermissionAccess)77, "c:\\temp");
171 public void ConstructorString ()
174 // FIXME: Adjust to run on Mac OS's
175 if (Path.VolumeSeparatorChar == ':')
176 pathToAdd = "c:\\temp";
180 p = new FileIOPermission(FileIOPermissionAccess.Read, pathToAdd);
181 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);
182 Assert.IsTrue (pathsInPermission.Length == 1, "Does not contain correct number of paths. Expected 1 but got: "+pathsInPermission.Length);
183 Assert.IsTrue(pathsInPermission[0] == pathToAdd, "Does not contain expected path from constructor: "+pathToAdd);
187 [ExpectedException (typeof (ArgumentNullException))]
188 public void ConstructorStringArray_Null ()
190 p = new FileIOPermission(FileIOPermissionAccess.Append, (string[])null);
194 public void ConstructorStringArray_Wildcard ()
197 // note: this is a valid path on UNIX so we must be able to protect it
198 p = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayBad);
200 catch (ArgumentException) {
202 Assert.Fail ("Wildcard * is valid in filenames");
203 // else it's normal for Windows to throw ArgumentException
205 catch (Exception e) {
206 Assert.Fail ("Bad or wrong exception: " + e.ToString ());
211 [ExpectedException (typeof (ArgumentException))]
212 public void ConstructorStringArray_InvalidAccess ()
214 p = new FileIOPermission((FileIOPermissionAccess)77, pathArrayGood);
218 public void ConstructorStringArray ()
220 p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);
221 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);
222 Assert.IsTrue (pathsInPermission.Length == 2, "Does not contain correct number of paths. Expected 2 but got: "+pathsInPermission.Length);
223 foreach (string s in pathsInPermission){
224 Assert.IsTrue (Array.IndexOf(pathsInPermission, s) >=0, "Unexpected path in the Permission: " + s);
229 public void AddPathListStringArray ()
231 p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);
232 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);
233 Assert.IsTrue (pathsInPermission.Length == 2, "Does not contain correct number of paths. Expected 2 but got: "+pathsInPermission.Length);
234 foreach (string s in pathsInPermission){
235 Assert.IsTrue (Array.IndexOf(pathsInPermission, s) >=0, "Unexpected path in the Permission: " + s);
238 p.AddPathList(FileIOPermissionAccess.Append, pathArrayGood);
239 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);
240 Assert.IsTrue (pathsInPermission.Length == 2, "Should still contain correct number Read paths. Expected 2 but got: "+pathsInPermission.Length);
241 foreach (string s in pathsInPermission){
242 Assert.IsTrue (Array.IndexOf(pathsInPermission, s) >=0, "Unexpected path in the Permission: " + s);
244 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Append);
245 Assert.IsTrue (pathsInPermission.Length == 2, "Should contain correct number of Append paths. Expected 2 but got: "+pathsInPermission.Length);
246 foreach (string s in pathsInPermission){
247 Assert.IsTrue (Array.IndexOf(pathsInPermission, s) >=0, "Unexpected path in the Permission: " + s);
252 public void Intersect ()
254 p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);
255 p.AllFiles = FileIOPermissionAccess.Append;
256 p.AllLocalFiles = FileIOPermissionAccess.Write;
258 unrestricted = new FileIOPermission(PermissionState.Unrestricted);
260 FileIOPermission intersection = (FileIOPermission)p.Intersect(unrestricted);
261 pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);
262 Assert.IsTrue (pathsInPermission.Length == 2, "Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length);
263 Assert.IsTrue((intersection.AllFiles & FileIOPermissionAccess.Append) != 0, "Should have Append bit in AllFiles.");
264 Assert.IsTrue((intersection.AllLocalFiles & FileIOPermissionAccess.Write) != 0, "Should have Write bit in AllLocalFiles.");
266 intersection = (FileIOPermission)unrestricted.Intersect(p);
267 pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);
268 Assert.IsTrue (pathsInPermission.Length == 2, "Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length);
269 Assert.IsTrue((intersection.AllFiles & FileIOPermissionAccess.Append) != 0, "Should have Append bit in AllFiles.");
270 Assert.IsTrue((intersection.AllLocalFiles & FileIOPermissionAccess.Write) != 0, "Should have Write bit in AllLocalFiles.");
272 p2 = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read, pathArrayGood2);
273 p2.AllFiles = FileIOPermissionAccess.Append | FileIOPermissionAccess.Write;
274 p2.AllLocalFiles = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read;
275 intersection = (FileIOPermission)p.Intersect(p2);
276 pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);
277 Assert.IsNotNull (pathsInPermission, "Should have some paths");
278 Assert.AreEqual (2, pathsInPermission.Length, "Should contain correct number of Read paths");
279 Assert.AreEqual ( FileIOPermissionAccess.Append, intersection.AllFiles, "Should have only Append bit in AllFiles.");
280 Assert.AreEqual ( FileIOPermissionAccess.Write, intersection.AllLocalFiles, "Should have only Write bit in AllLocalFiles.");
282 intersection = (FileIOPermission)p2.Intersect(p);
283 pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);
284 Assert.IsTrue (pathsInPermission.Length == 2, "Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length);
285 Assert.IsTrue(intersection.AllFiles == FileIOPermissionAccess.Append, "Should have only Append bit in AllFiles.");
286 Assert.IsTrue(intersection.AllLocalFiles == FileIOPermissionAccess.Write, "Should have only Write bit in AllLocalFiles.");
290 public void IsSubsetOf ()
292 unrestricted = new FileIOPermission(PermissionState.Unrestricted);
293 Assert.IsTrue(unrestricted.IsSubsetOf(unrestricted), "IsSubsetOf reflective test failed");
295 p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);
296 p.AllFiles = FileIOPermissionAccess.Append;
297 p.AllLocalFiles = FileIOPermissionAccess.Write;
298 Assert.IsTrue(p.IsSubsetOf(p), "#1 IsSubsetOf reflective test failed");
299 Assert.IsTrue(!unrestricted.IsSubsetOf(p), "#1 IsSubsetOf false test failed");
300 Assert.IsTrue(p.IsSubsetOf(unrestricted), "#1 IsSubsetOf true test failed");
302 p2 = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read, pathArrayGood2);
303 p2.AllFiles = FileIOPermissionAccess.Append | FileIOPermissionAccess.Write;
304 p2.AllLocalFiles = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read;
305 Assert.IsTrue(p2.IsSubsetOf(p2), "#2 IsSubsetOf reflective test failed");
306 Assert.IsTrue(p.IsSubsetOf(p2), "#2 IsSubsetOf true test failed");
307 Assert.IsTrue(!p2.IsSubsetOf(p), "#2 IsSubsetOf false test failed");
313 unrestricted = new FileIOPermission(PermissionState.Unrestricted);
314 p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);
316 FileIOPermission union = (FileIOPermission)unrestricted.Union(p);
317 pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);
318 Assert.IsTrue(union.IsUnrestricted(), "Should get an unrestricted permission");
319 Assert.IsTrue(pathsInPermission == null, "Path list should be empty");
321 union = (FileIOPermission)p.Union(unrestricted);
322 pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);
323 Assert.IsTrue(union.IsUnrestricted(), "Should get an unrestricted permission");
324 Assert.IsTrue(pathsInPermission == null, "Path list should be empty");
326 p2 = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayGood2);
328 union = (FileIOPermission)p.Union(p2);
329 pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);
330 Assert.IsTrue(pathsInPermission.Length == pathArrayGood.Length, "Path list should have 2 for Read");
331 pathsInPermission = union.GetPathList(FileIOPermissionAccess.Append);
332 Assert.IsTrue(pathsInPermission.Length == pathArrayGood2.Length, "Path list should have 3 for Append");
334 union = (FileIOPermission)p2.Union(p);
335 pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);
336 Assert.IsTrue(pathsInPermission.Length == pathArrayGood.Length, "Path list should have 2 for Read");
337 pathsInPermission = union.GetPathList(FileIOPermissionAccess.Append);
338 Assert.IsTrue(pathsInPermission.Length == pathArrayGood2.Length, "Path list should have 3 for Append");
342 public void Union_Bug79118 ()
344 string[] f1 = unix ? new string[] { "/tmp/one", "/tmp/two" } : new string[] { "c:\\temp\\one", "c:\\temp\\two" };
345 string[] f2 = unix ? new string[] { "/tmp/two" } : new string[] { "c:\\temp\\two" };
347 p = new FileIOPermission (FileIOPermissionAccess.Read, f1);
348 p2 = new FileIOPermission (FileIOPermissionAccess.Read, f2);
349 FileIOPermission union = (FileIOPermission) p.Union (p2);
351 string[] paths = union.GetPathList(FileIOPermissionAccess.Read);
352 Assert.AreEqual (2, paths.Length, "Length");
353 Assert.AreEqual (f1[0], paths[0], "0");
354 Assert.AreEqual (f1[1], paths[1], "1");
357 private void Partial (string msg, string[] path1, string[] path2, int expected)
359 p = new FileIOPermission (FileIOPermissionAccess.Read, path1);
360 p2 = new FileIOPermission (FileIOPermissionAccess.Read, path2);
361 FileIOPermission union = (FileIOPermission) p.Union (p2);
363 string[] paths = union.GetPathList(FileIOPermissionAccess.Read);
364 Assert.AreEqual (expected, paths.Length, msg + ".Length");
365 Assert.AreEqual (path1[0], paths[0], msg + "[0]");
367 Assert.AreEqual (path2[0], paths[1], msg + "[1]");
371 public void Union_Partial ()
373 string[] f1 = unix ? new string[] { "/dir/part" } : new string[] { "c:\\dir\\part" };
374 string[] f2 = unix ? new string[] { "/dir/partial" } : new string[] { "c:\\dir\\partial" };
375 Partial ("1", f1, f2, 2);
376 Partial ("2", f2, f1, 2);
378 f1 = unix ? new string[] { "/dir/part/" } : new string[] { "c:\\dir\\part\\" };
379 f2 = unix ? new string[] { "/dir/partial/" } : new string[] { "c:\\dir\\partial\\" };
380 Partial ("3", f1, f2, 2);
381 Partial ("4", f2, f1, 2);
383 f1 = unix ? new string[] { "/dir/part/ial" } : new string[] { "c:\\dir\\part\\ial" };
384 f2 = unix ? new string[] { "/dir/part/ial" } : new string[] { "c:\\dir\\part\\ial" };
385 Partial ("5", f1, f2, 1);
386 Partial ("6", f2, f1, 1);
390 public void FromXML ()
392 p = new FileIOPermission(PermissionState.None);
393 SecurityElement esd = new SecurityElement("IPermission");
394 esd.AddAttribute("class", "FileIOPermission");
395 esd.AddAttribute("version", "1");
396 esd.AddAttribute("Unrestricted", "true");
398 Assert.IsTrue(p.IsUnrestricted(), "Should get an unrestricted permission");
400 esd = new SecurityElement("IPermission");
401 esd.AddAttribute("class", "FileIOPermission");
402 esd.AddAttribute("version", "1");
403 // FIXME: Adjust to run on Mac OS's
404 if (Path.VolumeSeparatorChar == ':') {
405 esd.AddAttribute("Read", "c:\\temp;d:\\temp2");
406 esd.AddAttribute("Write", "c:\\temp;d:\\temp2;z:\\temp3");
409 esd.AddAttribute("Read", "/temp;/usr/temp2");
410 esd.AddAttribute("Write", "/temp;/usr/temp2;/usr/bin/temp3");
412 p = new FileIOPermission(PermissionState.None);
414 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);
415 Assert.IsTrue(pathsInPermission.Length == 2, "Path list should have 2 for Read");
416 pathsInPermission = p.GetPathList(FileIOPermissionAccess.Write);
417 Assert.IsTrue(pathsInPermission.Length == 3, "Path list should have 2 for Write");
423 p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);
424 SecurityElement esd = p.ToXml();
425 Assert.IsTrue(esd.Tag == "IPermission", "Esd tag incorrect");
426 Assert.IsTrue((String)esd.Attributes["version"] == "1", "Esd version incorrect");
427 string read = (String)esd.Attributes["Read"];
428 pathsInPermission = read.Split(';');
429 Assert.IsTrue(pathsInPermission.Length == 2, "Path list should have 2 for Read");
433 [Ignore("should compatibility go that far ?")]
434 public void ShortToLong ()
436 // on windows this returns a "short" (8.3) path and filename
437 string filename = Path.GetTempFileName ();
438 p = new FileIOPermission(FileIOPermissionAccess.Read, filename);
439 string[] files = p.GetPathList (FileIOPermissionAccess.Read);
440 Assert.AreEqual (1, files.Length, "GetPathList.Count");
441 // FIXME: here GetTempFileName != GetPathList[0] for MS but == for Mono
442 Assert.AreEqual (Path.GetFileName (filename), Path.GetFileName (files [0]), "Path.GetFileName(GetTempFileName)==Path.GetFileName(GetPathList[0])");
443 // note: this will fail on Linux as kernel32.dll isn't available
444 Assert.AreEqual (FilePathUtil.GetLongPathName (filename), files [0], "GetLongPathName(GetTempFileName)==GetPathList[0]");
448 [ExpectedException (typeof (ArgumentException))]
449 public void FileUrl ()
451 // file://... isn't accepted
452 string filename = Assembly.GetExecutingAssembly ().CodeBase;
453 p = new FileIOPermission (FileIOPermissionAccess.Read, filename);