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