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 ("", vs);
- }
+ if (handleViewState)
+ writer.WriteLine ("", _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 )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));
+ }
+ }
+}
+