Browse Source

2010-07-13 Marek Habersack <[email protected]>

	* BoundField.cs: implemented HtmlEncodeFormatString property
	(3.5+) and modified the way FormatDataValue works accordingly.

svn path=/trunk/mcs/; revision=160312
Marek Habersack 15 years ago
parent
commit
b58d43fc4c

+ 30 - 7
mcs/class/System.Web/System.Web.UI.WebControls/BoundField.cs

@@ -129,6 +129,14 @@ namespace System.Web.UI.WebControls
 			}
 		}
 
+		public virtual bool HtmlEncodeFormatString {
+			get { return ViewState.GetBool ("HtmlEncodeFormatString", true); }
+			set {
+				ViewState ["HtmlEncodeFormatString"] = value;
+				OnFieldChanged ();
+			}
+		}
+		
 		public override void ExtractValuesFromCell (IOrderedDictionary dictionary,
 			DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
 		{
@@ -180,20 +188,29 @@ namespace System.Web.UI.WebControls
 		protected virtual string FormatDataValue (object value, bool encode)
 		{
 			string res;
-			string stringValue = (value != null) ? value.ToString () : string.Empty;
+			bool htmlEncodeFormatString = HtmlEncodeFormatString;
+			string stringValue = (value != null) ? value.ToString () : String.Empty;
 			if (value == null || (stringValue.Length == 0 && ConvertEmptyStringToNull)) {
 				if (NullDisplayText.Length == 0) {
 					encode = false;
 					res = "&nbsp;";
 				} else
 					res = NullDisplayText;
-			} else if (DataFormatString.Length > 0)
-				res = string.Format (DataFormatString, value);
+			} else {
+				string format = DataFormatString;
+				if (!String.IsNullOrEmpty (format)) {
+					if (!encode || htmlEncodeFormatString)
+						res = String.Format (format, value);
+					else
+						res = String.Format (format, encode ? HttpUtility.HtmlEncode (stringValue) : stringValue);
+				} else
+					res = stringValue;
+			}
+			
+			if (encode && htmlEncodeFormatString)
+				return HttpUtility.HtmlEncode (res);
 			else
-				res = stringValue;
-				
-			if (encode) return HttpUtility.HtmlEncode (res);
-			else return res;
+				return res;
 		}
 		
 		protected virtual object GetValue (Control controlContainer)
@@ -223,6 +240,12 @@ namespace System.Web.UI.WebControls
 			return DataBinder.GetPropertyValue (dataItem, DataField);
 		}
 		
+		protected override void LoadViewState (object state)
+		{
+			// Why override?
+			base.LoadViewState (state);
+		}
+		
 		protected virtual void OnDataBindField (object sender, EventArgs e)
 		{
 			Control cell = (Control) sender;

+ 3 - 0
mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog

@@ -1,5 +1,8 @@
 2010-07-13  Marek Habersack  <[email protected]>
 
+	* BoundField.cs: implemented HtmlEncodeFormatString property
+	(3.5+) and modified the way FormatDataValue works accordingly.
+
 	* ListBox.cs, CheckBoxList.cs, ListControl.cs: VerifyMultiSelect
 	is not part of the official API. MultiSelect capability validation
 	is performed using an internal virtual method MultiSelectOk ().

+ 60 - 0
mcs/class/System.Web/Test/System.Web.UI.WebControls/BoundFieldTest.cs

@@ -49,6 +49,14 @@ using MonoTests.stand_alone.WebHarness;
 
 namespace MonoTests.System.Web.UI.WebControls
 {
+	class EncodingTest
+	{
+		public override string ToString ()
+		{
+			return "<EncodingTest>&";
+		}
+	}
+
 	class PokerBoundField : BoundField
 	{
 		public Button bindbutoon;
@@ -101,6 +109,11 @@ namespace MonoTests.System.Web.UI.WebControls
 		public Control GetControl {
 			get { return base.Control; }
 		}
+
+		public object DoSaveViewState ()
+		{
+			return SaveViewState ();
+		}
 	}
 
 
@@ -299,6 +312,53 @@ namespace MonoTests.System.Web.UI.WebControls
 			bf.DataFormatString = "-{0,8:G}-";
 			result = bf.DoFormatDataValue (10, false);
 			Assert.AreEqual ("-      10-", result, "FormatDataValueWithFormat");
+
+			bf.DataFormatString = "-{0:X}-";
+			result = bf.DoFormatDataValue (10, true);
+			Assert.AreEqual ("-A-", result, "FormatDataValueWithFormatAndHtmlEncode");
+
+			bf.DataFormatString = "-{0:X}-";
+			result = bf.DoFormatDataValue (10, false);
+			Assert.AreEqual ("-A-", result, "FormatDataValueWithFormatAndNoHtmlEncode");
+
+			bf.HtmlEncodeFormatString = false;
+			bf.DataFormatString = "-{0:X}-";
+			result = bf.DoFormatDataValue (10, true);
+			Assert.AreEqual ("-10-", result, "NoHtmlEncodeFormatString_HtmlEncode");
+
+			bf.DataFormatString = "-{0:X}-";
+			result = bf.DoFormatDataValue (10, false);
+			Assert.AreEqual ("-A-", result, "NoHtmlEncodeFormatString_NoHtmlEncode");
+		}
+
+		[Test]
+		public void HtmlEncodeFormatString ()
+		{
+			string formatString = "<script>alert ('{0}');</script>"; 
+			var bf = new PokerBoundField ();
+
+			Assert.IsTrue (bf.HtmlEncodeFormatString, "#A1-2");
+			Assert.IsTrue (bf.HtmlEncode, "#A1-2");
+			Assert.IsTrue (bf.DoSupportsHtmlEncode, "#A1-3");
+
+			bf.DataFormatString = formatString;
+#if NET_4_0
+			Assert.AreEqual ("&lt;script&gt;alert (&#39;&lt;test&gt;&#39;);&lt;/script&gt;", bf.DoFormatDataValue ("<test>", true), "#A2");
+#else
+			Assert.AreEqual ("&lt;script&gt;alert ('&lt;test&gt;');&lt;/script&gt;", bf.DoFormatDataValue ("<test>", true), "#A2");
+#endif
+			Assert.AreEqual (String.Format (formatString, "<test>"), bf.DoFormatDataValue ("<test>", false), "#A3");
+
+			bf.HtmlEncodeFormatString = false;
+			Assert.AreEqual ("<script>alert ('&lt;test&gt;');</script>", bf.DoFormatDataValue ("<test>", true), "#A4");
+
+			var ec = new EncodingTest ();
+			bf.HtmlEncodeFormatString = true;
+#if NET_4_0
+			Assert.AreEqual ("&lt;script&gt;alert (&#39;&lt;EncodingTest&gt;&amp;&#39;);&lt;/script&gt;", bf.DoFormatDataValue (ec, true), "#A4");
+#else
+			Assert.AreEqual ("&lt;script&gt;alert ('&lt;EncodingTest&gt;&amp;');&lt;/script&gt;", bf.DoFormatDataValue (ec, true), "#A4");
+#endif
 		}
 
 		[Test]