Merge pull request #2227 from esdrubal/tzparse
[mono.git] / mcs / class / System.Web / System.Web / VirtualPathUtility.cs
index 2387ad93bffbd82a6c6b24b24bc897ca3aaeb69c..12bcf8a7e699e9e80666a8cde443b724ff0223d7 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-
+using System.Collections.Specialized;
+using System.Web.Configuration;
 using System.Web.Util;
 using System.Text;
+using Microsoft.Win32;
 
 namespace System.Web {
 
-#if NET_2_0
-       public
-#endif
-       static class VirtualPathUtility
+       public static class VirtualPathUtility
        {
+               static bool monoSettingsVerifyCompatibility;
+               static bool runningOnWindows;
+               
+               static VirtualPathUtility ()
+               {
+                       try {
+                               runningOnWindows = RuntimeHelpers.RunningOnWindows;
+                               var monoSettings = WebConfigurationManager.GetWebApplicationSection ("system.web/monoSettings") as MonoSettingsSection;
+                               if (monoSettings != null)
+                                       monoSettingsVerifyCompatibility = monoSettings.VerificationCompatibility != 1;
+                       } catch {
+                               // ignore
+                       }
+               }
+               
                public static string AppendTrailingSlash (string virtualPath)
                {
                        if (virtualPath == null)
@@ -59,13 +73,13 @@ namespace System.Web {
                        if (IsRooted (relativePath))
                                return Normalize (relativePath);
 
-                       if (basePath [basePath.Length - 1] != '/') {
-                               if (basePath.Length > 1) {
+                       int basePathLen = basePath.Length;
+                       if (basePath [basePathLen - 1] != '/') {
+                               if (basePathLen > 1) {
                                        int lastSlash = basePath.LastIndexOf ('/');
                                        if (lastSlash >= 0)
                                                basePath = basePath.Substring (0, lastSlash + 1);
-                               }
-                               else { // "~" only
+                               } else { // "~" only
                                        basePath += "/";
                                }
                        }
@@ -83,15 +97,16 @@ namespace System.Web {
                        if (normalize)
                                virtualPath = Normalize (virtualPath);
 
-                       if (IsAppRelative (virtualPath) && virtualPath.Length < 3) { // "~" or "~/"
+                       int vpLen = virtualPath.Length;
+                       if (IsAppRelative (virtualPath) && vpLen < 3) { // "~" or "~/"
                                virtualPath = ToAbsolute (virtualPath);
+                               vpLen = virtualPath.Length;
                        }
                        
-                       if (virtualPath.Length == 1 && virtualPath [0] == '/') { // "/"
+                       if (vpLen == 1 && virtualPath [0] == '/') // "/"
                                return null;
-                       }
 
-                       int last = virtualPath.LastIndexOf ('/', virtualPath.Length - 2, virtualPath.Length - 2);
+                       int last = virtualPath.LastIndexOf ('/', vpLen - 2, vpLen - 2);
                        if (last > 0)
                                return virtualPath.Substring (0, last + 1);
                        else
@@ -238,7 +253,7 @@ namespace System.Web {
                        if (virtualPath.Length == 1 && virtualPath [0] == '~')
                                return apppath;
 
-                       return ToAbsolute (virtualPath,apppath);
+                       return ToAbsolute (virtualPath, apppath, normalize);
                }
 
                // If virtualPath is: 
@@ -250,7 +265,7 @@ namespace System.Web {
                        return ToAbsolute (virtualPath, applicationPath, true);
                }
 
-               public static string ToAbsolute (string virtualPath, string applicationPath, bool normalize)
+               internal static string ToAbsolute (string virtualPath, string applicationPath, bool normalize)
                {
                        if (StrUtils.IsNullOrEmpty (applicationPath))
                                throw new ArgumentNullException ("applicationPath");
@@ -313,7 +328,7 @@ namespace System.Web {
 
                static char [] path_sep = { '/' };
 
-               static string Normalize (string path)
+               internal static string Normalize (string path)
                {
                        if (!IsRooted (path))
                                throw new ArgumentException (String.Format ("The relative virtual path '{0}' is not allowed here.", path));
@@ -455,12 +470,31 @@ namespace System.Web {
                }
 
                // See: http://support.microsoft.com/kb/932552
+               // See: https://bugzilla.novell.com/show_bug.cgi?id=509163
                static readonly char[] invalidVirtualPathChars = {':', '*'};
+               static readonly string aspNetVerificationKey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\ASP.NET";
                internal static bool IsValidVirtualPath (string path)
                {
                        if (path == null)
                                return false;
-                       
+
+                       bool doValidate = true;
+                       if (runningOnWindows) {
+                               try {
+                                       object v = Registry.GetValue (aspNetVerificationKey, "VerificationCompatibility", null);
+                                       if (v != null && v is int)
+                                               doValidate = (int)v != 1;
+                               } catch {
+                                       // ignore
+                               }
+                       }
+
+                       if (doValidate)
+                               doValidate = monoSettingsVerifyCompatibility;
+
+                       if (!doValidate)
+                               return true;
+
                        return path.IndexOfAny (invalidVirtualPathChars) == -1;
                }
        }