1 //
2 // Authors:
3 //   Marek Habersack <mhabersack@novell.com>
4 //
5 // Copyright (C) 2010 Novell, Inc (http://novell.com/)
6 //
7 
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Configuration;
30 using System.Web;
31 using System.Web.Configuration;
32 
33 namespace System.Web.Util
34 {
35 	public class RequestValidator
36 	{
37 		static RequestValidator current;
38 		static Lazy <RequestValidator> lazyLoader;
39 
40 		// The stack trace from .NET shows it uses Lazy <T>:
41 		//
42 		//  Server stack trace:
43 		//    at System.Web.Configuration.ConfigUtil.GetType(String typeName, String propertyName, ConfigurationElement configElement, XmlNode node, Boolean checkAptcaBit, Boolean ignoreCase)
44 		//    at System.Web.Util.RequestValidator.GetCustomValidatorFromConfig()
45 		//    at System.Lazy`1.CreateValue()
46 		//
47 		public static RequestValidator Current {
48 			get {
49 				if (current == null)
50 					current = lazyLoader.Value;
51 
52 				return current;
53 			}
54 
55 			set {
56 				if (value == null)
57 					throw new ArgumentNullException ("value");
58 
59 				current = value;
60 			}
61 		}
62 
RequestValidator()63 		static RequestValidator ()
64 		{
65 			lazyLoader = new Lazy <RequestValidator> (new Func <RequestValidator> (LoadConfiguredValidator));
66 		}
67 
RequestValidator()68 		public RequestValidator ()
69 		{
70 		}
71 
IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)72 		protected internal virtual bool IsValidRequestString (HttpContext context, string value, RequestValidationSource requestValidationSource,
73 								      string collectionKey, out int validationFailureIndex)
74 		{
75 			validationFailureIndex = 0;
76 
77 			return !HttpRequest.IsInvalidString (value, out validationFailureIndex);
78 		}
79 
ParseTypeName(string spec, out string typeName, out string assemblyName)80 		static void ParseTypeName (string spec, out string typeName, out string assemblyName)
81 		{
82 			try {
83 				if (String.IsNullOrEmpty (spec)) {
84 					typeName = null;
85 					assemblyName = null;
86 					return;
87 				}
88 
89 				int comma = spec.IndexOf (',');
90 				if (comma == -1) {
91 					typeName = spec;
92 					assemblyName = null;
93 					return;
94 				}
95 
96 				typeName = spec.Substring (0, comma).Trim ();
97 				assemblyName = spec.Substring (comma + 1).Trim ();
98 			} catch {
99 				typeName = spec;
100 				assemblyName = null;
101 			}
102 		}
103 
LoadConfiguredValidator()104 		static RequestValidator LoadConfiguredValidator ()
105 		{
106 			HttpRuntimeSection runtimeConfig = HttpRuntime.Section;
107 			Type validatorType = null;
108 			string typeSpec = runtimeConfig.RequestValidationType;
109 
110 			try {
111 				validatorType = HttpApplication.LoadType <RequestValidator> (typeSpec, true);
112 			} catch (TypeLoadException ex) {
113 				string typeName, assemblyName;
114 
115 				ParseTypeName (typeSpec, out typeName, out assemblyName);
116 				throw new ConfigurationErrorsException (
117 					String.Format ("Could not load type '{0}' from assembly '{1}'.", typeName, assemblyName),
118 					ex);
119 			}
120 
121 			return (RequestValidator) Activator.CreateInstance (validatorType);
122 		}
123 	}
124 }
125