2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / corlib / Test / System.Security.Permissions / FileIOPermissionTest.cs
1 //\r
2 // MonoTests.System.Security.Permissions.FileIOPermissionTest.cs\r
3 //\r
4 // Author:\r
5 //   Nick Drochak (ndrochak@gol.com)\r
6 //\r
7 // (C) 2001-2002 Nick Drochak II\r
8 //\r
9 // Note: Only Unix and Windows file paths are tested.  To run the tests on Mac OS's\r
10 // search for the "FIXME" notes below and adjust accordingly.\r
11 \r
12 using System;\r
13 using System.IO;\r
14 using System.Runtime.InteropServices;
15 using System.Reflection;\r
16 using System.Security;\r
17 using System.Security.Permissions;\r
18 using System.Text;\r
19 \r
20 using NUnit.Framework;\r
21 \r
22 namespace MonoTests.System.Security.Permissions {\r
23 #if !TARGET_JVM\r
24         public class FilePathUtil {\r
25                 [DllImport("kernel32.dll")]\r
26                 private static extern uint GetLongPathName (string shortPath, \r
27                         StringBuilder buffer, uint bufLength);\r
28 \r
29                 static public string GetLongPathName (string somePath) \r
30                 {\r
31                         StringBuilder buffer = new StringBuilder(260);\r
32                         if (0 != GetLongPathName (somePath, buffer, (uint) buffer.Capacity))\r
33                                 return buffer.ToString ();\r
34                         else\r
35                                 return null;\r
36                 }\r
37 \r
38                 [DllImport("kernel32.dll", SetLastError=true)] \r
39                 private static extern uint GetShortPathName ( string longPath, \r
40                         StringBuilder buffer, uint bufLength);\r
41 \r
42                 static public string GetShortPathName (string somePath) \r
43                 {\r
44                         StringBuilder buffer = new StringBuilder(260);\r
45                         if (0 != GetShortPathName (somePath, buffer, (uint) buffer.Capacity))\r
46                                 return buffer.ToString ();\r
47                         else\r
48                                 return null;\r
49                 }\r
50         }\r
51 #endif\r
52 \r
53         [TestFixture]\r
54         public class FileIOPermissionTest : Assertion {\r
55                 \r
56                 string[] pathArrayGood;\r
57                 string[] pathArrayBad;\r
58                 FileIOPermission p;\r
59                 FileIOPermission p2;\r
60                 string[] pathsInPermission;\r
61                 string[] pathArrayGood2;\r
62                 FileIOPermission unrestricted;\r
63 \r
64                 private string filename;
65                 private bool unix;\r
66 \r
67                 [SetUp]\r
68                 public void SetUp () \r
69                 {\r
70                         Environment.CurrentDirectory = Path.GetTempPath();\r
71                         filename = Path.GetTempFileName ();\r
72
73                         int os = (int) Environment.OSVersion.Platform;
74                         unix = ((os == 4) || (os == 128) || (os == 6));
75 \r
76                         p = null;\r
77                         pathsInPermission = null;\r
78                         pathArrayGood = new string[2];\r
79                         pathArrayBad = new string[2];\r
80                         pathArrayGood2 = new string[3];\r
81                         // FIXME: Adjust to run on Mac OS's\r
82                         if (Path.VolumeSeparatorChar == ':') {\r
83                                 pathArrayGood[0] = "c:\\temp1";\r
84                                 pathArrayGood[1] = "d:\\temp2";\r
85                                 pathArrayBad[0] = "c:\\temp1";\r
86                                 pathArrayBad[1] = "d:\\temp*";\r
87                                 pathArrayGood2[0] = "c:\\temp1";\r
88                                 pathArrayGood2[1] = "d:\\temp2";\r
89                                 pathArrayGood2[2] = "z:\\something";\r
90                         }\r
91                         else {\r
92                                 pathArrayGood[0] = "/temp1";\r
93                                 pathArrayGood[1] = "/usr/temp2";\r
94                                 pathArrayBad[0] = "/temp1";\r
95                                 pathArrayBad[1] = "/usr/temp*"; // not really bad under Unix...\r
96                                 pathArrayGood2[0] = "/temp1";\r
97                                 pathArrayGood2[1] = "/usr/temp2";\r
98                                 pathArrayGood2[2] = "/usr/bin/something";\r
99                         }\r
100                 }\r
101 \r
102                 [TearDown]\r
103                 public void TearDown () \r
104                 {\r
105                         if (File.Exists (filename))\r
106                                 File.Delete (filename);\r
107                 }\r
108 \r
109                 [Test]\r
110                 public void ConstructorPermissionState ()\r
111                 {\r
112                         p = new FileIOPermission(PermissionState.None);\r
113                         AssertEquals("Should be Restricted", false, p.IsUnrestricted());\r
114                         p = new FileIOPermission(PermissionState.Unrestricted);\r
115                         AssertEquals("Should be Unrestricted", true, p.IsUnrestricted());\r
116                         try{\r
117                                 p = new FileIOPermission((PermissionState)77);\r
118                                 Fail("Should have thrown an exception on invalid PermissionState");\r
119                         }\r
120                         catch{\r
121                                 // we should be here if things are working.  nothing to do\r
122                         }\r
123                 }\r
124 \r
125                 [Test]\r
126                 [ExpectedException (typeof (ArgumentNullException))]\r
127                 public void ConstructorString_Null () \r
128                 {\r
129                         p = new FileIOPermission(FileIOPermissionAccess.Append, (string)null);\r
130                 }\r
131 \r
132                 [Test]\r
133                 [ExpectedException (typeof (ArgumentException))]\r
134                 public void ConstructorString_NotRooted ()\r
135                 {\r
136                         p = new FileIOPermission(FileIOPermissionAccess.Append, "this path is not rooted");\r
137                 }\r
138 \r
139                 [Test]\r
140                 [ExpectedException (typeof (ArgumentException))]\r
141                 public void ConstructorString_InvalidPath () \r
142                 {\r
143                         p = new FileIOPermission(FileIOPermissionAccess.Append, "<this is not a valid path>");\r
144                 }\r
145 \r
146                 [Test]\r
147                 public void ConstructorString_Wildcard () \r
148                 {
149                         try {
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]);
152                         }
153                         catch (ArgumentException) {
154                                 if (unix)
155                                         Fail ("Wildcard * is valid in filenames");
156                                 // else it's normal for Windows to throw ArgumentException
157                         }
158                         catch (Exception e) {
159                                 Fail ("Bad or wrong exception: " + e.ToString ());
160                         }\r
161                 }\r
162 \r
163                 [Test]\r
164                 [ExpectedException (typeof (ArgumentException))]\r
165                 public void ConstructorString_InvalidAccess () \r
166                 {\r
167                         p = new FileIOPermission((FileIOPermissionAccess)77, "c:\\temp");\r
168                 }\r
169 \r
170                 [Test]\r
171                 public void ConstructorString ()\r
172                 {\r
173                         string pathToAdd;\r
174                         // FIXME: Adjust to run on Mac OS's\r
175                         if (Path.VolumeSeparatorChar == ':')\r
176                                 pathToAdd = "c:\\temp";\r
177                         else\r
178                                 pathToAdd = "/temp";\r
179 \r
180                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathToAdd);\r
181                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);\r
182                         Assert("Does not contain correct number of paths. Expected 1 but got: "+pathsInPermission.Length, pathsInPermission.Length == 1);\r
183                         Assert("Does not contain expected path from constructor: "+pathToAdd, pathsInPermission[0] == pathToAdd);\r
184                 }\r
185 \r
186                 [Test]\r
187                 [ExpectedException (typeof (ArgumentNullException))]\r
188                 public void ConstructorStringArray_Null () \r
189                 {\r
190                         p = new FileIOPermission(FileIOPermissionAccess.Append, (string[])null);\r
191                 }\r
192 \r
193                 [Test]\r
194                 public void ConstructorStringArray_Wildcard () \r
195                 {\r
196                         try {
197                                 // note: this is a valid path on UNIX so we must be able to protect it
198                                 p = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayBad);\r
199                         }
200                         catch (ArgumentException) {
201                                 if (unix)
202                                         Fail ("Wildcard * is valid in filenames");
203                                 // else it's normal for Windows to throw ArgumentException
204                         }
205                         catch (Exception e) {
206                                 Fail ("Bad or wrong exception: " + e.ToString ());
207                         }\r
208                 }\r
209 \r
210                 [Test]\r
211                 [ExpectedException (typeof (ArgumentException))]\r
212                 public void ConstructorStringArray_InvalidAccess () \r
213                 {\r
214                         p = new FileIOPermission((FileIOPermissionAccess)77, pathArrayGood);\r
215                 }\r
216 \r
217                 [Test]\r
218                 public void ConstructorStringArray () \r
219                 {\r
220                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);\r
221                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);\r
222                         Assert("Does not contain correct number of paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
223                         foreach (string s in pathsInPermission){\r
224                                 Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0);\r
225                         }\r
226                 }\r
227 \r
228                 [Test]\r
229                 public void AddPathListStringArray ()\r
230                 {\r
231                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);\r
232                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);\r
233                         Assert("Does not contain correct number of paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
234                         foreach (string s in pathsInPermission){\r
235                                 Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0);\r
236                         }\r
237 \r
238                         p.AddPathList(FileIOPermissionAccess.Append, pathArrayGood);\r
239                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);\r
240                         Assert("Should still contain correct number Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
241                         foreach (string s in pathsInPermission){\r
242                                 Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0);\r
243                         }\r
244                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Append);\r
245                         Assert("Should contain correct number of Append paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
246                         foreach (string s in pathsInPermission){\r
247                                 Assert("Unexpected path in the Permission: " + s, Array.IndexOf(pathsInPermission, s) >=0);\r
248                         }\r
249                 }\r
250 \r
251                 [Test]\r
252                 public void Intersect ()\r
253                 {\r
254                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);\r
255                         p.AllFiles = FileIOPermissionAccess.Append;\r
256                         p.AllLocalFiles = FileIOPermissionAccess.Write;\r
257                         \r
258                         unrestricted = new FileIOPermission(PermissionState.Unrestricted);\r
259                         \r
260                         FileIOPermission intersection = (FileIOPermission)p.Intersect(unrestricted);\r
261                         pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);\r
262                         Assert("Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
263                         Assert("Should have Append bit in AllFiles.", (intersection.AllFiles & FileIOPermissionAccess.Append) != 0);\r
264                         Assert("Should have Write bit in AllLocalFiles.", (intersection.AllLocalFiles & FileIOPermissionAccess.Write) != 0);\r
265 \r
266                         intersection = (FileIOPermission)unrestricted.Intersect(p);\r
267                         pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);\r
268                         Assert("Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
269                         Assert("Should have Append bit in AllFiles.", (intersection.AllFiles & FileIOPermissionAccess.Append) != 0);\r
270                         Assert("Should have Write bit in AllLocalFiles.", (intersection.AllLocalFiles & FileIOPermissionAccess.Write) != 0);\r
271 \r
272                         p2 = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read, pathArrayGood2);\r
273                         p2.AllFiles = FileIOPermissionAccess.Append | FileIOPermissionAccess.Write;\r
274                         p2.AllLocalFiles = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read;\r
275                         intersection = (FileIOPermission)p.Intersect(p2);\r
276                         pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);\r
277                         AssertNotNull ("Should have some paths", pathsInPermission);\r
278                         AssertEquals ("Should contain correct number of Read paths", 2, pathsInPermission.Length);\r
279                         AssertEquals ("Should have only Append bit in AllFiles.",  FileIOPermissionAccess.Append, intersection.AllFiles);\r
280                         AssertEquals ("Should have only Write bit in AllLocalFiles.",  FileIOPermissionAccess.Write, intersection.AllLocalFiles);\r
281 \r
282                         intersection = (FileIOPermission)p2.Intersect(p);\r
283                         pathsInPermission = intersection.GetPathList(FileIOPermissionAccess.Read);\r
284                         Assert("Should contain correct number of Read paths. Expected 2 but got: "+pathsInPermission.Length, pathsInPermission.Length == 2);\r
285                         Assert("Should have only Append bit in AllFiles.", intersection.AllFiles == FileIOPermissionAccess.Append);\r
286                         Assert("Should have only Write bit in AllLocalFiles.", intersection.AllLocalFiles == FileIOPermissionAccess.Write);\r
287                 }\r
288 \r
289                 [Test]\r
290                 public void IsSubsetOf ()\r
291                 {\r
292                         unrestricted = new FileIOPermission(PermissionState.Unrestricted);\r
293                         Assert("IsSubsetOf reflective test failed", unrestricted.IsSubsetOf(unrestricted));\r
294 \r
295                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);\r
296                         p.AllFiles = FileIOPermissionAccess.Append;\r
297                         p.AllLocalFiles = FileIOPermissionAccess.Write;\r
298                         Assert("#1 IsSubsetOf reflective test failed", p.IsSubsetOf(p));\r
299                         Assert("#1 IsSubsetOf false test failed", !unrestricted.IsSubsetOf(p));\r
300                         Assert("#1 IsSubsetOf true test failed", p.IsSubsetOf(unrestricted));\r
301 \r
302                         p2 = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read, pathArrayGood2);\r
303                         p2.AllFiles = FileIOPermissionAccess.Append | FileIOPermissionAccess.Write;\r
304                         p2.AllLocalFiles = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read;\r
305                         Assert("#2 IsSubsetOf reflective test failed", p2.IsSubsetOf(p2));\r
306                         Assert("#2 IsSubsetOf true test failed", p.IsSubsetOf(p2));\r
307                         Assert("#2 IsSubsetOf false test failed", !p2.IsSubsetOf(p));\r
308                 }\r
309 \r
310                 [Test]\r
311                 public void Union ()\r
312                 {\r
313                         unrestricted = new FileIOPermission(PermissionState.Unrestricted);\r
314                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);\r
315 \r
316                         FileIOPermission union = (FileIOPermission)unrestricted.Union(p);\r
317                         pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);\r
318                         Assert("Should get an unrestricted permission", union.IsUnrestricted());\r
319                         Assert("Path list should be empty", pathsInPermission == null);\r
320 \r
321                         union = (FileIOPermission)p.Union(unrestricted);\r
322                         pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);\r
323                         Assert("Should get an unrestricted permission", union.IsUnrestricted());\r
324                         Assert("Path list should be empty", pathsInPermission == null);\r
325 \r
326                         p2 = new FileIOPermission(FileIOPermissionAccess.Append, pathArrayGood2);\r
327 \r
328                         union = (FileIOPermission)p.Union(p2);\r
329                         pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);\r
330                         Assert("Path list should have 2 for Read", pathsInPermission.Length == pathArrayGood.Length);\r
331                         pathsInPermission = union.GetPathList(FileIOPermissionAccess.Append);\r
332                         Assert("Path list should have 3 for Append", pathsInPermission.Length == pathArrayGood2.Length);\r
333 \r
334                         union = (FileIOPermission)p2.Union(p);\r
335                         pathsInPermission = union.GetPathList(FileIOPermissionAccess.Read);\r
336                         Assert("Path list should have 2 for Read", pathsInPermission.Length == pathArrayGood.Length);\r
337                         pathsInPermission = union.GetPathList(FileIOPermissionAccess.Append);\r
338                         Assert("Path list should have 3 for Append", pathsInPermission.Length == pathArrayGood2.Length);\r
339                 }
340
341                 [Test]
342                 public void Union_Bug79118 ()
343                 {
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" };
346
347                         p = new FileIOPermission (FileIOPermissionAccess.Read, f1);
348                         p2 = new FileIOPermission (FileIOPermissionAccess.Read, f2);
349                         FileIOPermission union = (FileIOPermission) p.Union (p2);
350
351                         string[] paths = union.GetPathList(FileIOPermissionAccess.Read);
352                         AssertEquals ("Length", 2, paths.Length);
353                         AssertEquals ("0", f1[0], paths[0]);
354                         AssertEquals ("1", f1[1], paths[1]);
355                 }
356
357                 private void Partial (string msg, string[] path1, string[] path2, int expected)
358                 {
359                         p = new FileIOPermission (FileIOPermissionAccess.Read, path1);
360                         p2 = new FileIOPermission (FileIOPermissionAccess.Read, path2);
361                         FileIOPermission union = (FileIOPermission) p.Union (p2);
362
363                         string[] paths = union.GetPathList(FileIOPermissionAccess.Read);
364                         AssertEquals (msg + ".Length", expected, paths.Length);
365                         AssertEquals (msg + "[0]", path1[0], paths[0]);
366                         if (expected > 1)
367                                 AssertEquals (msg + "[1]", path2[0], paths[1]);
368                 }\r
369 \r
370                 [Test]
371                 public void Union_Partial ()
372                 {
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);
377
378                         f1 = unix ? new string[] { "/dir/part/" } : new string[] { "c:\\dir\\part\\" };
379                         f2 = unix ? new string[] { "/dir/partial/" } : new string[] { "c:\\dir\\partial\\" };\r
380                         Partial ("3", f1, f2, 2);\r
381                         Partial ("4", f2, f1, 2);
382
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" };\r
385                         Partial ("5", f1, f2, 1);
386                         Partial ("6", f2, f1, 1);
387                 }\r
388 \r
389                 [Test]\r
390                 public void FromXML ()\r
391                 {\r
392                         p = new FileIOPermission(PermissionState.None);\r
393                         SecurityElement esd = new SecurityElement("IPermission");\r
394                         esd.AddAttribute("class", "FileIOPermission");\r
395                         esd.AddAttribute("version", "1");\r
396                         esd.AddAttribute("Unrestricted", "true");\r
397                         p.FromXml(esd);\r
398                         Assert("Should get an unrestricted permission", p.IsUnrestricted());\r
399 \r
400                         esd = new SecurityElement("IPermission");\r
401                         esd.AddAttribute("class", "FileIOPermission");\r
402                         esd.AddAttribute("version", "1");\r
403                         // FIXME: Adjust to run on Mac OS's\r
404                         if (Path.VolumeSeparatorChar == ':') {\r
405                                 esd.AddAttribute("Read", "c:\\temp;d:\\temp2");\r
406                                 esd.AddAttribute("Write", "c:\\temp;d:\\temp2;z:\\temp3");\r
407                         }\r
408                         else {\r
409                                 esd.AddAttribute("Read", "/temp;/usr/temp2");\r
410                                 esd.AddAttribute("Write", "/temp;/usr/temp2;/usr/bin/temp3");\r
411                         }\r
412                         p = new FileIOPermission(PermissionState.None);\r
413                         p.FromXml(esd);\r
414                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Read);\r
415                         Assert("Path list should have 2 for Read", pathsInPermission.Length == 2);\r
416                         pathsInPermission = p.GetPathList(FileIOPermissionAccess.Write);\r
417                         Assert("Path list should have 2 for Write", pathsInPermission.Length == 3);\r
418                 }\r
419 \r
420                 [Test]\r
421                 public void ToXML ()\r
422                 {\r
423                         p = new FileIOPermission(FileIOPermissionAccess.Read, pathArrayGood);\r
424                         SecurityElement esd = p.ToXml();\r
425                         Assert("Esd tag incorrect", esd.Tag == "IPermission");\r
426                         Assert("Esd version incorrect", (String)esd.Attributes["version"] == "1");\r
427                         string read = (String)esd.Attributes["Read"];\r
428                         pathsInPermission = read.Split(';');\r
429                         Assert("Path list should have 2 for Read", pathsInPermission.Length == 2);\r
430                 }\r
431 #if !TARGET_JVM\r
432                 [Test]\r
433                 [Ignore("should compatibility go that far ?")]\r
434                 public void ShortToLong () \r
435                 {\r
436                         // on windows this returns a "short" (8.3) path and filename\r
437                         string filename = Path.GetTempFileName ();\r
438                         p = new FileIOPermission(FileIOPermissionAccess.Read, filename);\r
439                         string[] files = p.GetPathList (FileIOPermissionAccess.Read);\r
440                         AssertEquals ("GetPathList.Count", 1, files.Length);\r
441                         // FIXME: here GetTempFileName != GetPathList[0] for MS but == for Mono\r
442                         AssertEquals ("Path.GetFileName(GetTempFileName)==Path.GetFileName(GetPathList[0])", Path.GetFileName (filename), Path.GetFileName (files [0]));\r
443                         // note: this will fail on Linux as kernel32.dll isn't available\r
444                         AssertEquals ("GetLongPathName(GetTempFileName)==GetPathList[0]", FilePathUtil.GetLongPathName (filename), files [0]);\r
445                 }
446 #endif
447                 [Test]\r
448                 [ExpectedException (typeof (ArgumentException))]\r
449                 public void FileUrl ()
450                 {
451                         // file://... isn't accepted
452                         string filename = Assembly.GetExecutingAssembly ().CodeBase;\r
453                         p = new FileIOPermission (FileIOPermissionAccess.Read, filename);\r
454                 }\r
455         }\r
456 }\r