All pastes #262468 Raw Edit

Miscellany

public text v1 · immutable
#262468 ·published 2006-11-30 15:50 UTC
rendered paste body
Index: IStateFormatter.cs
===================================================================
--- IStateFormatter.cs	(revision 68748)
+++ IStateFormatter.cs	(working copy)
@@ -28,16 +28,20 @@
 //
 
 
-#if NET_2_0
 using System;
 
 namespace System.Web.UI
 {
-	public interface IStateFormatter
+#if NET_2_0
+	public
+#else
+	internal
+#endif
+	interface IStateFormatter
 	{
 		object Deserialize (string serializationState);
 		string Serialize (object state);
 	}
 }
-#endif
 
+
Index: Page.cs
===================================================================
--- Page.cs	(revision 68748)
+++ Page.cs	(working copy)
@@ -86,7 +86,7 @@
 	private HttpContext _context;
 	private ValidatorCollection _validators;
 	private bool renderingForm;
-	private object _savedViewState;
+	private string _savedViewState;
 	private ArrayList _requiresPostBack;
 	private ArrayList _requiresPostBackCopy;
 	private ArrayList requiresPostDataChanged;
@@ -100,6 +100,7 @@
 	string clientTarget;
 	ClientScriptManager scriptManager;
 	bool allow_load; // true when the Form collection belongs to this page (GetTypeHashCode)
+	PageStatePersister page_state_persister;
 
 	[EditorBrowsable (EditorBrowsableState.Never)]
 #if NET_2_0
@@ -320,6 +321,13 @@
 		set { _viewStateMac = value; }
 	}
 
+#if NET_1_1
+	internal bool EnableViewStateMacInternal {
+		get { return _viewStateMac; }
+		set { _viewStateMac = value; }
+	}
+#endif
+	
 	[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
 	[Browsable (false), DefaultValue ("")]
 	[WebSysDescription ("The URL of a page used for error redirection.")]
@@ -968,45 +976,17 @@
 			postBackScriptRendered = true;
 		}
 
-		if (handleViewState) {
-			string vs = GetViewStateString ();
-			writer.Write ("<input type=\"hidden\" name=\"__VIEWSTATE\" ");
-			writer.WriteLine ("value=\"{0}\" />", vs);
-		}
+		if (handleViewState)
+			writer.WriteLine ("<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"{0}\" />", _savedViewState);
 
 		scriptManager.WriteClientScriptBlocks (writer);
 	}
 
-	internal LosFormatter GetFormatter ()
+	internal IStateFormatter GetFormatter ()
 	{
-#if NET_2_0
-		PagesSection config = (PagesSection) WebConfigurationManager.GetSection ("system.web/pages");
-#else
-		PagesConfiguration config = PagesConfiguration.GetInstance (_context);
-#endif
-		byte [] vkey = null;
-		if (config.EnableViewStateMac) {
-#if NET_2_0
-			MachineKeySection mconfig = (MachineKeySection) WebConfigurationManager.GetSection ("system.web/machineKey");
-			vkey = mconfig.ValidationKeyBytes;
-#else
-			MachineKeyConfig mconfig = HttpContext.GetAppConfig ("system.web/machineKey") as MachineKeyConfig;
-			vkey = mconfig.ValidationKey;
-#endif
-		}
-
-		return new LosFormatter (config.EnableViewStateMac, vkey);
+		return new ObjectStateFormatter (this);
 	}
 
-	string GetViewStateString ()
-	{
-		if (_savedViewState == null)
-			return null;
-
-		LosFormatter fmt = GetFormatter ();
-		return fmt.SerializeToBase64 (_savedViewState);
-	}
-
 	internal object GetSavedViewState ()
 	{
 		return _savedViewState;
@@ -1457,46 +1437,69 @@
 	[EditorBrowsable (EditorBrowsableState.Advanced)]
 	protected virtual void SavePageStateToPersistenceMedium (object viewState)
 	{
-		_savedViewState = viewState;
+		PageStatePersister persister = this.PageStatePersister;
+		if (persister == null)
+			return;
+		Pair pair = viewState as Pair;
+		if (pair != null) {
+			persister.ViewState = pair.First;
+			persister.ControlState = pair.Second;
+		} else
+			persister.ViewState = viewState;
+		persister.Save ();
 	}
 
+	internal string RawViewState {
+		get {
+			NameValueCollection postdata = _requestValueCollection;
+			string view_state;
+			if (postdata == null || (view_state = postdata ["__VIEWSTATE"]) == null)
+				return null;
+
+			if (view_state == "")
+				return null;
+			return view_state;
+		}
+		set { _savedViewState = value; }
+	}
+
+#if NET_2_0
+	protected virtual 
+#else
+	internal
+#endif
+	PageStatePersister PageStatePersister {
+		get {
+			if (page_state_persister == null)
+				page_state_persister = new HiddenFieldPageStatePersister (this);
+			return page_state_persister;
+		}
+	}
+	
 	[EditorBrowsable (EditorBrowsableState.Advanced)]
 	protected virtual object LoadPageStateFromPersistenceMedium ()
 	{
-		NameValueCollection postdata = _requestValueCollection;
-		string view_state;
-		if (postdata == null || (view_state = postdata ["__VIEWSTATE"]) == null)
+		PageStatePersister persister = this.PageStatePersister;
+		if (persister == null)
 			return null;
-
-		if (view_state == "")
-			return null;
-
-		LosFormatter fmt = GetFormatter ();
-		try {
-			return fmt.Deserialize (view_state);
-		} catch (Exception e) {
-			throw new HttpException ("Error restoring page viewstate.", e);
-		}
+		persister.Load ();
+		return new Pair (persister.ViewState, persister.ControlState);
 	}
 
 	internal void LoadPageViewState()
 	{
-		object sState = LoadPageStateFromPersistenceMedium ();
+		Pair sState = LoadPageStateFromPersistenceMedium () as Pair;
 		if (sState != null) {
-#if NET_2_0
-			Triplet data = (Triplet) sState;
 			if (allow_load) {
-				LoadPageControlState (data.Third);
-				LoadViewStateRecursive (data.First);
-				_requiresPostBack = data.Second as ArrayList;
-			}
-#else
-			Pair pair = (Pair) sState;
-			if (allow_load) {
-				LoadViewStateRecursive (pair.First);
-				_requiresPostBack = pair.Second as ArrayList;
-			}
+#if NET_2_0
+				LoadPageControlState (sState.Second);
 #endif
+				Pair vsr = sState.First as Pair;
+				if (vsr != null) {
+					LoadViewStateRecursive (vsr.First);
+					_requiresPostBack = vsr.Second as ArrayList;
+				}
+			}
 		}
 	}
 
@@ -1511,27 +1514,23 @@
 
 		object viewState = SaveViewStateRecursive ();
 		object reqPostback = (_requiresPostBack != null && _requiresPostBack.Count > 0) ? _requiresPostBack : null;
+		Pair vsr = null;
 
-#if NET_2_0
-		Triplet triplet = new Triplet ();
-		triplet.First = viewState;
-		triplet.Second = reqPostback;
-		triplet.Third = controlState;
-
-		if (triplet.First == null && triplet.Second == null && triplet.Third == null)
-			triplet = null;
-			
-		SavePageStateToPersistenceMedium (triplet);
-#else
+		if (viewState != null || reqPostback != null)
+			vsr = new Pair (viewState, reqPostback);
 		Pair pair = new Pair ();
-		pair.First = viewState;
-		pair.Second = reqPostback;
 
-		if (pair.First == null && pair.Second == null)
-			pair = null;
-			
-		SavePageStateToPersistenceMedium (pair);
+		pair.First = vsr;
+#if NET_2_0
+		pair.Second = controlState;
+#else
+		pair.Second = null;
 #endif
+		if (pair.First == null && pair.Second == null)
+			SavePageStateToPersistenceMedium (null);
+		else
+			SavePageStateToPersistenceMedium (pair);		
+
 	}
 
 	public virtual void Validate ()
Index: PageStatePersister.cs
===================================================================
--- PageStatePersister.cs	(revision 68748)
+++ PageStatePersister.cs	(working copy)
@@ -26,50 +26,48 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 namespace System.Web.UI
 {
-	public abstract class PageStatePersister
+#if NET_2_0
+	public
+#else
+	internal
+#endif
+	abstract class PageStatePersister
 	{
+		object control_state;
+		object view_state;
+		Page page;
+		IStateFormatter state_formatter;
+		
 		protected PageStatePersister (Page page)
 		{
+			if (page == null)
+				throw new ArgumentNullException ("page");
+			this.page = page;
 		}
 
-		public object ControlState 
-		{
-			get {
-				throw new NotImplementedException ();
-			}
-			set {
-				throw new NotImplementedException ();
-			}
+		public object ControlState  {
+			get { return control_state; }
+			set { control_state = value; }
 		}
 
-		public object ViewState 
-		{
-			get {
-				throw new NotImplementedException ();
-			}
-			set {
-				throw new NotImplementedException ();
-			}
+		public object ViewState  {
+			get { return view_state; }
+			set { view_state = value; }
 		}
 
-		protected Page Page 
-		{
-			get {
-				throw new NotImplementedException ();
-			}
-			set {
-				throw new NotImplementedException ();
-			}
+		protected Page Page {
+			get { return page; }
+			set { page = value; }
 		}
 
 		protected IStateFormatter StateFormatter 
 		{
 			get {
-				throw new NotImplementedException ();
+				if (state_formatter == null)
+					state_formatter = page.GetFormatter ();
+				return state_formatter;
 			}
 		}
 
@@ -78,4 +76,3 @@
 		public abstract void Save ();
 	}
 }
-#endif
\ No newline at end of file
Index: LosFormatter.cs
===================================================================
--- LosFormatter.cs	(revision 68748)
+++ LosFormatter.cs	(working copy)
@@ -39,12 +39,11 @@
 	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class LosFormatter {
 
-		ObjectStateFormatter osf = new ObjectStateFormatter ();
-		bool enable_mac;
-		HashAlgorithm algo;
+		ObjectStateFormatter osf;
 		
 		public LosFormatter ()
 		{
+			osf = new ObjectStateFormatter ();
 		}
 
 #if NET_1_1
@@ -61,27 +60,12 @@
 #endif
 		LosFormatter (bool enableMac, byte[] macKeyModifier)
 		{
-			this.enable_mac = enableMac;
 			if (enableMac)
-				algo = new HMACSHA1 (macKeyModifier);
+				osf = new ObjectStateFormatter (macKeyModifier);
+			else
+				osf = new ObjectStateFormatter ();
 		}
 
-		int ValidateInput (byte [] data, int offset, int size)
-		{
-			int hash_size = algo.HashSize / 8;
-			if (size != 0 && size < hash_size)
-				throw new HttpException ("Unable to validate data.");
-
-			int data_length = size - hash_size;
-			MemoryStream data_stream = new MemoryStream (data, offset, data_length, false, false);
-			byte [] hash = algo.ComputeHash (data_stream);
-			for (int i = 0; i < hash_size; i++) {
-				if (hash [i] != data [data_length + i])
-					throw new HttpException ("Unable to validate data.");
-			}
-			return data_length;
-		}
-
 		public object Deserialize (Stream stream)
 		{
 			if (stream == null)
@@ -116,24 +100,12 @@
 			if (input == null)
 				return null;
 
-			if (!enable_mac)
-				return osf.Deserialize (input);
-
-			byte [] buffer = Convert.FromBase64String (input);
-			int length = buffer.Length;
-			length = ValidateInput (buffer, 0, length);
-			return osf.Deserialize (new MemoryStream (buffer, 0, length, false, false));
+			return osf.Deserialize (input);
 		}
 
 		internal string SerializeToBase64 (object value)
 		{
-			MemoryStream ms = new MemoryStream ();
-			osf.Serialize (ms, value);
-			if (enable_mac && ms.Length > 0) {
-				byte [] hash = algo.ComputeHash (ms.GetBuffer (), 0, (int) ms.Length);
-				ms.Write (hash, 0, hash.Length);
-			}
-			return Convert.ToBase64String (ms.GetBuffer (), 0, (int) ms.Length);
+			return osf.Serialize (value);
 		}
 
 		public void Serialize (Stream stream, object value)
Index: ClientScriptManager.cs
===================================================================
--- ClientScriptManager.cs	(revision 68748)
+++ ClientScriptManager.cs	(working copy)
@@ -473,7 +473,7 @@
 		{
 			if (!page.EnableEventValidation || fieldValue == null || fieldValue.Length == 0)
 				return;
-			LosFormatter fmt = page.GetFormatter ();
+			IStateFormatter fmt = page.GetFormatter ();
 			eventValidationValues = (List <int>)fmt.Deserialize (fieldValue);
 		}
 		
@@ -482,8 +482,8 @@
 			if (!page.EnableEventValidation || eventValidationValues == null || eventValidationValues.Count == 0)
 				return;
 			eventValidationValues.Sort ();
-			LosFormatter fmt = page.GetFormatter ();
-			RegisterHiddenField (EventStateFieldName, fmt.SerializeToBase64 (eventValidationValues));
+			IStateFormatter fmt = page.GetFormatter ();
+			RegisterHiddenField (EventStateFieldName, fmt.Serialize (eventValidationValues));
 		}
 
 		internal string EventStateFieldName
Index: ObjectStateFormatter.cs
===================================================================
--- ObjectStateFormatter.cs	(revision 68748)
+++ ObjectStateFormatter.cs	(working copy)
@@ -44,6 +44,8 @@
 using System.Web.UI.WebControls;
 using System.Web.Util;
 using System.Diagnostics;
+using System.Security.Cryptography;
+using System.Web.Configuration;
 
 namespace System.Web.UI {
 #if NET_2_0
@@ -51,11 +53,85 @@
 #else
 	internal
 #endif
-	sealed class ObjectStateFormatter : IFormatter
+	sealed class ObjectStateFormatter : IFormatter, IStateFormatter
+	{
+		Page page;
+		HashAlgorithm algo;
+		byte [] vkey;
+
+		internal ObjectStateFormatter ()
+		{
+		}
+		
+		internal ObjectStateFormatter (Page page)
+		{
+			this.page = page;
+		}
+
+		internal ObjectStateFormatter (byte [] vkey)
+		{
+			this.vkey = vkey;
+		}
+		
+		internal bool EnableMac {
+			get {
+				if (page == null) {
+					if (vkey == null)
+						return false;
+					return true;
+				} else {
+				
 #if NET_2_0
-		, IStateFormatter
+					return page.EnableViewStateMac;
+#elif NET_1_1
+					return page.EnableViewStateMacInternal;
+#else
+					return false;
 #endif
-	{
+				}
+			}
+		}
+
+		internal HashAlgorithm GetAlgo () {
+			if (algo != null)
+				return algo;
+			if (!EnableMac)
+				return null;
+			
+			byte [] algoKey;
+			if (page != null) {
+#if NET_2_0
+				MachineKeySection mconfig = (MachineKeySection) WebConfigurationManager.GetSection ("system.web/machineKey");
+				algoKey = mconfig.ValidationKeyBytes;
+#else
+				MachineKeyConfig mconfig = HttpContext.GetAppConfig ("system.web/machineKey") as MachineKeyConfig;
+				algoKey = mconfig.ValidationKey;
+#endif
+			} else
+				algoKey = vkey;
+			
+			return new HMACSHA1 (algoKey);
+		}
+
+		static int ValidateInput (HashAlgorithm algo, byte [] data, int offset, int size)
+		{
+			if (algo == null)
+				throw new HttpException ("Unable to validate data.");
+			
+			int hash_size = algo.HashSize / 8;
+			if (size != 0 && size < hash_size)
+				throw new HttpException ("Unable to validate data.");
+
+			int data_length = size - hash_size;
+			MemoryStream data_stream = new MemoryStream (data, offset, data_length, false, false);
+			byte [] hash = algo.ComputeHash (data_stream);
+			for (int i = 0; i < hash_size; i++) {
+				if (hash [i] != data [data_length + i])
+					throw new HttpException ("Unable to validate data.");
+			}
+			return data_length;
+		}
+		
 		public object Deserialize (Stream inputStream)
 		{
 			if (inputStream == null)
@@ -68,15 +144,20 @@
 		{
 			if (inputString == null)
 				throw new ArgumentNullException ("inputString");
-#if !NET_2_0
+#if NET_2_0
+			if (inputString.Length == 0)
+				throw new ArgumentNullException ("inputString");
+#else
 			if (inputString == "")
 				return "";
 #endif
 			byte [] buffer = Convert.FromBase64String (inputString);
-			if (buffer == null || buffer.Length == 0)
+			int length;
+			if (buffer == null || (length = buffer.Length) == 0)
 				throw new ArgumentNullException ("inputString");
-
-			return Deserialize (new MemoryStream (buffer));
+			if (page != null && EnableMac)
+				length = ValidateInput (GetAlgo (), buffer, 0, length);
+			return Deserialize (new MemoryStream (buffer, 0, length, false, false));
 		}
 		
 		public string Serialize (object stateGraph)
@@ -90,7 +171,14 @@
 			#if TRACE
 				ms.WriteTo (File.OpenWrite (Path.GetTempFileName ()));
 			#endif
-			
+			if (EnableMac && ms.Length > 0) {
+				HashAlgorithm algo = GetAlgo ();
+				if (algo != null) {
+					byte [] hash = algo.ComputeHash (ms.GetBuffer (), 0, (int) ms.Length);
+					ms.Write (hash, 0, hash.Length);
+				}
+				
+			}
 			return Convert.ToBase64String (ms.GetBuffer (), 0, (int) ms.Length);
 		}
 		
Index: HiddenFieldPageStatePersister.cs
===================================================================
--- HiddenFieldPageStatePersister.cs	(revision 0)
+++ HiddenFieldPageStatePersister.cs	(revision 0)
@@ -0,0 +1,66 @@
+//
+// System.Web.Compilation.AppCodeCompiler: A compiler for the App_Code folder
+//
+// Authors:
+//   Marek Habersack (grendello@gmail.com)
+//
+// (C) 2006 Marek Habersack
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System.Security.Permissions;
+
+namespace System.Web.UI 
+{
+#if NET_2_0
+	// CAS
+        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+	public
+#else
+	internal
+#endif
+	class HiddenFieldPageStatePersister : PageStatePersister
+	{
+		public HiddenFieldPageStatePersister (Page page)
+			: base(page)
+		{
+		}
+		
+		public override void Load ()
+		{
+			IStateFormatter formatter = StateFormatter;
+			Pair pair = formatter.Deserialize (Page.RawViewState) as Pair;
+			if (pair != null) {
+				ViewState = pair.First;
+				ControlState = pair.Second;
+			}
+		}
+
+		public override void Save ()
+		{
+			IStateFormatter formatter = StateFormatter;
+			Page.RawViewState = formatter.Serialize (new Pair (ViewState, ControlState));
+		}
+	}
+}
+