minor fix for bug 9520:
[mono.git] / mcs / class / System / Test / System.Net / WebUtilityTest.cs
1 //
2 // System.Net.WebUtilityTest.cs
3 //
4 // copied and edited from System.Web.HttpUtilityTest.cs
5 //
6 // Author:
7 //      Sebastien Pouliot  <sebastien@ximian.com>
8 //      Mike Kestner <mkestner@novell.com>
9 //
10 // Copyright (C) 2005, 2010 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 #if NET_4_0 && !MOBILE
33
34 using System;
35 using System.Text;
36 using System.Net;
37 using System.IO;
38 using System.Collections.Specialized;
39
40 using NUnit.Framework;
41
42 namespace MonoTests.System.Net {
43
44         [TestFixture]
45         public class WebUtilityTest {
46
47                 [Test]
48                 public void HtmlEncode_LtGt ()
49                 {
50                         Assert.AreEqual ("&lt;script&gt;", WebUtility.HtmlEncode ("<script>"));
51                 }
52
53                 // Notes:
54                 // * this is to avoid a regression that would cause Mono to 
55                 //   fail item #3 of the XSS vulnerabilities listed at:
56                 //   http://it-project.ru/andir/docs/aspxvuln/aspxvuln.en.xml
57                 //   we didn't fall the first time so let's ensure we never will
58                 // * The author notes that Microsoft has decided not to fix 
59                 //   this issue (hence the NotDotNet category).
60
61                 [Test]
62                 [Category ("NotDotNet")]
63 #if TARGET_JVM
64                 [Ignore ("TD #6954")]
65 #endif
66                 public void HtmlEncode_XSS ()
67                 {
68                         string problem = "\xff1cscript\xff1e";  // unicode looks alike <script>
69                         byte[] utf8data = Encoding.UTF8.GetBytes (problem);
70                         Encoding win1251 = Encoding.GetEncoding ("windows-1251");
71                         byte[] windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
72                         // now it's a real problem
73                         Assert.AreEqual ("<script>", Encoding.ASCII.GetString (windata), "<script>");
74
75                         string encoded = WebUtility.HtmlEncode (problem);
76                         Assert.AreEqual ("&#65308;script&#65310;", encoded, "&#65308;script&#65310;");
77                         
78                         utf8data = Encoding.UTF8.GetBytes (encoded);
79                         windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
80                         Assert.AreEqual ("&#65308;script&#65310;", Encoding.ASCII.GetString (windata), "ok");
81                 }
82
83                 [Test]
84 #if !TARGET_JVM
85                 [Category ("NotWorking")]
86 #endif
87                 public void HtmlEncode () {
88                         for (char c = char.MinValue; c < char.MaxValue; c++) {
89                                 String exp = HtmlEncode (c.ToString ());
90                                 String act = WebUtility.HtmlEncode (c.ToString ());
91                                 Assert.AreEqual (exp, act, "HtmlEncode " + c.ToString () + " [" + (int) c + "]");
92                         }
93                 }
94                 
95                 string HtmlEncode (string s) {
96                         if (s == null)
97                                 return null;
98
99                         bool needEncode = false;
100                         for (int i = 0; i < s.Length; i++) {
101                                 char c = s [i];
102                                 if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159) {
103                                         needEncode = true;
104                                         break;
105                                 }
106                         }
107
108                         if (!needEncode)
109                                 return s;
110
111                         StringBuilder output = new StringBuilder ();
112
113                         int len = s.Length;
114                         for (int i = 0; i < len; i++)
115                                 switch (s [i]) {
116                                 case '&':
117                                         output.Append ("&amp;");
118                                         break;
119                                 case '>':
120                                         output.Append ("&gt;");
121                                         break;
122                                 case '<':
123                                         output.Append ("&lt;");
124                                         break;
125                                 case '"':
126                                         output.Append ("&quot;");
127                                         break;
128                                 default:
129                                         // MS starts encoding with &# from 160 and stops at 255.
130                                         // We don't do that. One reason is the 65308/65310 unicode
131                                         // characters that look like '<' and '>'.
132                                         if (s [i] > 159 && s [i] < 256) {
133                                                 output.Append ("&#");
134                                                 output.Append (((int) s [i]).ToString ());
135                                                 output.Append (";");
136                                         }
137                                         else {
138                                                 output.Append (s [i]);
139                                         }
140                                         break;
141                                 }
142                         return output.ToString ();
143                 }
144
145                 
146                 [Test]
147                 public void EscapedCharacters ()
148                 {
149                         for (int i = 0; i < 256; i++) {
150                                 string str = new string ((char) i, 1);
151                                 string encoded = WebUtility.HtmlEncode (str);
152                                 if ((i > 159 && i < 256 ) || i == '&' || i == '<' || i == '>' || i == '"') {
153                                         if (encoded [0] != '&' || encoded [encoded.Length - 1] != ';')
154                                                 Assert.Fail ("Failed for i = " + i);
155                                 } else if (encoded.Length != 1) {
156                                         Assert.Fail ("Wrong length for i = " + i);
157                                 }
158                         }
159                 }
160
161                 [Test]
162                 public void Decode1 ()
163                 {
164                         Assert.AreEqual ("\xE9", WebUtility.HtmlDecode ("&#233;"));
165                 }
166
167                 [Test]
168                 public void RoundTrip ()
169                 {
170                         string x = "<html>& hello+= world!";
171                         string y = WebUtility.HtmlEncode (x);
172                         string z = WebUtility.HtmlDecode (y);
173                         Assert.AreEqual (x, z);
174                 }
175
176                 [Test]
177                 public void LooksLikeEntity ()
178                 {
179                         string str = "<%# \"hola\" + \"/somepage.aspx?ItemID=\" + DataBinder.Eval(Container.DataItem,\"Country\")" +
180                                         " + \"&mid=\" + ModuleID + \"&pageindex=\" + Request.Params.Get(\"pageindex\") %>";
181                         Assert.AreEqual (str, WebUtility.HtmlDecode (str));
182                 }
183         }
184 }
185 #endif
186