New test.
[mono.git] / mcs / class / corlib / System.Security.Permissions / FileIOPermission.cs
index 325814962232490193a049f0d3a3ec31e7337eb9..72f7566cc66c1a241fe54e64399d507aa74f91be 100644 (file)
@@ -6,7 +6,7 @@
 //     Sebastien Pouliot  <sebastien@ximian.com>
 //
 // Copyright (C) 2001 Nick Drochak, All Rights Reserved\r
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -39,12 +39,36 @@ using System.Security.AccessControl;
 \r
 namespace System.Security.Permissions {\r
 \r
+#if NET_2_0
+       [ComVisible (true)]
+#endif
        [Serializable]\r
        public sealed class FileIOPermission\r
                 : CodeAccessPermission, IBuiltInPermission, IUnrestrictedPermission {\r
 
                private const int version = 1;
-               private static char[] m_badCharacters = {'\"','<', '>', '|', '*', '?'};\r
+
+#if NET_2_0
+               private static char[] BadPathNameCharacters;
+               private static char[] BadFileNameCharacters;
+
+               static FileIOPermission ()
+               {
+                       // we keep a local (static) copies to avoid calls/allocations
+                       BadPathNameCharacters = Path.GetInvalidPathChars ();
+                       BadFileNameCharacters = Path.GetInvalidFileNameChars ();
+               }
+#else
+               private static char[] m_badCharacters;
+
+               static FileIOPermission ()
+               {
+                       // note: deprecated in 2.0 as InvalidPathChars is an array (i.e. items can be
+                       // modified). Anyway we keep our own copy, which should be called by the 
+                       // security manager before anyone has the chance to change it.
+                       m_badCharacters = (char[]) Path.InvalidPathChars.Clone ();
+               }
+#endif\r
 
                private bool m_Unrestricted = false;\r
                private FileIOPermissionAccess m_AllFilesAccess = FileIOPermissionAccess.NoAccess;\r
@@ -93,13 +117,13 @@ namespace System.Security.Permissions {
                }
 
 #if NET_2_0
-               [MonoTODO ("Access Control isn't implemented")]
+               [MonoTODO ("(2.0) Access Control isn't implemented")]
                public FileIOPermission (FileIOPermissionAccess access, AccessControlActions control, string path)
                {
                        throw new NotImplementedException ();
                }\r
 \r
-               [MonoTODO ("Access Control isn't implemented")]
+               [MonoTODO ("(2.0) Access Control isn't implemented")]
                public FileIOPermission (FileIOPermissionAccess access, AccessControlActions control, string[] pathList)
                {\r
                        throw new NotImplementedException ();
@@ -381,14 +405,14 @@ namespace System.Security.Permissions {
                }\r
 \r
 #if NET_2_0
-               [MonoTODO]
+               [MonoTODO ("(2.0)")]
                [ComVisible (false)]
                public override bool Equals (object obj)
                {
                        return false;
                }
 
-               [MonoTODO]
+               [MonoTODO ("(2.0)")]
                [ComVisible (false)]
                public override int GetHashCode ()
                {
@@ -410,7 +434,7 @@ namespace System.Security.Permissions {
                                && (writeList.Count == 0) && (pathList.Count == 0));
                }
 
-               private FileIOPermission Cast (IPermission target)
+               private static FileIOPermission Cast (IPermission target)
                {
                        if (target == null)
                                return null;
@@ -423,7 +447,7 @@ namespace System.Security.Permissions {
                        return fiop;
                }
 
-               internal void ThrowInvalidFlag (FileIOPermissionAccess access, bool context) 
+               internal static void ThrowInvalidFlag (FileIOPermissionAccess access, bool context) 
                {
                        string msg = null;
                        if (context)
@@ -433,12 +457,26 @@ namespace System.Security.Permissions {
                        throw new ArgumentException (String.Format (msg, access), "access");
                }
 
-               internal void ThrowIfInvalidPath (string path)
+               internal static void ThrowIfInvalidPath (string path)
                {
+#if NET_2_0
+                       string dir = Path.GetDirectoryName (path);
+                       if ((dir != null) && (dir.LastIndexOfAny (BadPathNameCharacters) >= 0)) {
+                               string msg = String.Format (Locale.GetText ("Invalid path characters in path: '{0}'"), path);\r
+                               throw new ArgumentException (msg, "path");\r
+                       }
+\r
+                       string fname = Path.GetFileName (path);
+                       if ((fname != null) && (fname.LastIndexOfAny (BadFileNameCharacters) >= 0)) {
+                               string msg = String.Format (Locale.GetText ("Invalid filename characters in path: '{0}'"), path);\r
+                               throw new ArgumentException (msg, "path");\r
+                       }
+#else
                        if (path.LastIndexOfAny (m_badCharacters) >= 0) {\r
                                string msg = String.Format (Locale.GetText ("Invalid characters in path: '{0}'"), path);\r
                                throw new ArgumentException (msg, "path");\r
-                       }\r
+                       }
+#endif\r
                        // LAMESPEC: docs don't say it must be a rooted path, but the MS implementation enforces it, so we will too.\r
                        if (!Path.IsPathRooted (path)) {
                                string msg = Locale.GetText ("Absolute path information is required.");
@@ -446,7 +484,7 @@ namespace System.Security.Permissions {
                        }
                }
 \r
-               internal void ThrowIfInvalidPath (string[] paths)
+               internal static void ThrowIfInvalidPath (string[] paths)
                {
                        foreach (string path in paths)
                                ThrowIfInvalidPath (path);
@@ -466,12 +504,12 @@ namespace System.Security.Permissions {
                }\r
 
                // note: all path in IList are already "full paths"
-               internal bool KeyIsSubsetOf (IList local, IList target)
+               internal static bool KeyIsSubsetOf (IList local, IList target)
                {
                        bool result = false;
                        foreach (string l in local) {
                                foreach (string t in target) {
-                                       if (l.StartsWith (t)) {
+                                       if (Path.IsPathSubsetOf (t, l)) {
                                                result = true;
                                                break;
                                        }
@@ -482,7 +520,7 @@ namespace System.Security.Permissions {
                        return true;
                }
 
-               internal void UnionKeys (IList list, string[] paths)
+               internal static void UnionKeys (IList list, string[] paths)
                {
                        foreach (string path in paths) {
                                int len = list.Count;
@@ -490,36 +528,36 @@ namespace System.Security.Permissions {
                                        list.Add (path);
                                }
                                else {
-                                       for (int i=0; i < len; i++) {
+                                       int i;
+                                       for (i=0; i < len; i++) {
                                                string s = (string) list [i];
-                                               if (s.StartsWith (path)) {
+                                               if (Path.IsPathSubsetOf (path, s)) {
                                                        // replace (with reduced version)
                                                        list [i] = path;
                                                        break;
                                                }
-                                               else if (path.StartsWith (s)) {
+                                               else if (Path.IsPathSubsetOf (s, path)) {
                                                        // no need to add
                                                        break;
                                                }
-                                               else {
-                                                       list.Add (path);
-                                                       break;
-                                               }
+                                       }
+                                       if (i == len) {
+                                               list.Add (path);
                                        }
                                }
                        }
                }
 
-               internal void IntersectKeys (IList local, IList target, IList result)
+               internal static void IntersectKeys (IList local, IList target, IList result)
                {
                        foreach (string l in local) {
                                foreach (string t in target) {
                                        if (t.Length > l.Length) {
-                                               if (t.StartsWith (l))
+                                               if (Path.IsPathSubsetOf (l ,t))
                                                        result.Add (t);
                                        }
                                        else {
-                                               if (l.StartsWith (t))
+                                               if (Path.IsPathSubsetOf (t, l))
                                                        result.Add (l);
                                        }
                                }