++2010-06-01 Marek Habersack <mhabersack@novell.com>
++
++ * HttpRuntimeSection.cs: added 4.0 properties
++ MaxQueryLengthString, MaxUrlLength, EncoderType and
++ RelaxedUrlToFileSystemMapping.
++
2010-05-17 Marek Habersack <mhabersack@novell.com>
* BuildProvider.cs: made the Extension property case-insensitive
static ConfigurationProperty requestPathInvalidCharactersProp;
static ConfigurationProperty requestValidationTypeProp;
static ConfigurationProperty requestValidationModeProp;
++ static ConfigurationProperty maxQueryStringLengthProp;
++ static ConfigurationProperty maxUrlLengthProp;
++ static ConfigurationProperty encoderTypeProp;
++ static ConfigurationProperty relaxedUrlToFileSystemMappingProp;
#endif
static ConfigurationPropertyCollection properties;
PropertyHelper.VersionConverter,
PropertyHelper.DefaultValidator,
ConfigurationPropertyOptions.None);
++ maxQueryStringLengthProp = new ConfigurationProperty ("maxQueryStringLength", typeof (int), 2048,
++ TypeDescriptor.GetConverter (typeof (int)),
++ PropertyHelper.IntFromZeroToMaxValidator,
++ ConfigurationPropertyOptions.None);
++ maxUrlLengthProp = new ConfigurationProperty ("maxUrlLength", typeof (int), 260,
++ TypeDescriptor.GetConverter (typeof (int)),
++ PropertyHelper.IntFromZeroToMaxValidator,
++ ConfigurationPropertyOptions.None);
++ encoderTypeProp = new ConfigurationProperty ("encoderType", typeof (string), "System.Web.Util.HttpEncoder",
++ TypeDescriptor.GetConverter (typeof (string)),
++ PropertyHelper.NonEmptyStringValidator,
++ ConfigurationPropertyOptions.None);
++ relaxedUrlToFileSystemMappingProp = new ConfigurationProperty ("relaxedUrlToFileSystemMapping", typeof (bool), false);
#endif
properties = new ConfigurationPropertyCollection();
properties.Add (requestPathInvalidCharactersProp);
properties.Add (requestValidationTypeProp);
properties.Add (requestValidationModeProp);
++ properties.Add (maxQueryStringLengthProp);
++ properties.Add (maxUrlLengthProp);
++ properties.Add (encoderTypeProp);
++ properties.Add (relaxedUrlToFileSystemMappingProp);
#endif
}
}
[ConfigurationProperty ("requestValidationType", DefaultValue = "System.Web.Util.RequestValidator")]
-- [StringValidatorAttribute(MinLength = 1)]
++ [StringValidator (MinLength = 1)]
public string RequestValidationType {
get { return (string) base [requestValidationTypeProp]; }
set { base [requestValidationTypeProp] = value; }
get { return (Version) base [requestValidationModeProp]; }
set { base [requestValidationModeProp] = value; }
}
++
++ [IntegerValidator (MinValue = 0)]
++ [ConfigurationProperty ("maxQueryStringLength", DefaultValue = "2048")]
++ public int MaxQueryStringLength {
++ get { return (int) base [maxQueryStringLengthProp]; }
++ set { base [maxQueryStringLengthProp] = value; }
++ }
++
++ [IntegerValidator (MinValue = 0)]
++ [ConfigurationProperty ("maxUrlLength", DefaultValue = "260")]
++ public int MaxUrlLength {
++ get { return (int) base [maxUrlLengthProp]; }
++ set { base [maxUrlLengthProp] = value; }
++ }
++
++ [StringValidator (MinLength = 1)]
++ [ConfigurationProperty ("encoderType", DefaultValue = "System.Web.Util.HttpEncoder")]
++ public string EncoderType {
++ get { return (string) base [encoderTypeProp]; }
++ set { base [encoderTypeProp] = value; }
++ }
++
++ [ConfigurationProperty ("relaxedUrlToFileSystemMapping", DefaultValue = "False")]
++ public bool RelaxedUrlToFileSystemMapping {
++ get { return (bool) base [relaxedUrlToFileSystemMappingProp]; }
++ set { base [relaxedUrlToFileSystemMappingProp] = value; }
++ }
#endif
protected override ConfigurationPropertyCollection Properties {
get { return properties; }
++2010-06-01 Marek Habersack <mhabersack@novell.com>
++
++ * HttpEncoder.cs: added. A 4.0 type but also used in 2.0 profile,
++ internally.
++
2010-03-06 Marek Habersack <mhabersack@novell.com>
* RequestValidator.cs: added
--- /dev/null
--- /dev/null
++//
++// Authors:
++// Patrik Torstensson (Patrik.Torstensson@labs2.com)
++// Wictor Wilén (decode/encode functions) (wictor@ibizkit.se)
++// Tim Coleman (tim@timcoleman.com)
++// Gonzalo Paniagua Javier (gonzalo@ximian.com)
++
++// Marek Habersack <mhabersack@novell.com>
++//
++// (C) 2005-2010 Novell, Inc (http://novell.com/)
++//
++
++//
++// 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;
++using System.Collections.Generic;
++using System.Configuration;
++using System.IO;
++using System.Text;
++using System.Web.Configuration;
++
++namespace System.Web.Util
++{
++#if NET_4_0
++ public
++#endif
++ class HttpEncoder
++ {
++ static char [] hexChars = "0123456789abcdef".ToCharArray ();
++ static object entitiesLock = new object ();
++ static SortedDictionary <string, char> entities;
++#if NET_4_0
++ static Lazy <HttpEncoder> defaultEncoder;
++ static Lazy <HttpEncoder> currentEncoderLazy;
++#else
++ static HttpEncoder defaultEncoder;
++#endif
++ static HttpEncoder currentEncoder;
++
++ static IDictionary <string, char> Entities {
++ get {
++ lock (entitiesLock) {
++ if (entities == null)
++ InitEntities ();
++
++ return entities;
++ }
++ }
++ }
++
++ public static HttpEncoder Current {
++ get {
++#if NET_4_0
++ if (currentEncoder == null)
++ currentEncoder = currentEncoderLazy.Value;
++#endif
++ return currentEncoder;
++ }
++#if NET_4_0
++ set {
++ if (value == null)
++ throw new ArgumentNullException ("value");
++ currentEncoder = value;
++ }
++#endif
++ }
++
++ public static HttpEncoder Default {
++ get {
++#if NET_4_0
++ return defaultEncoder.Value;
++#else
++ return defaultEncoder;
++#endif
++ }
++ }
++
++ static HttpEncoder ()
++ {
++#if NET_4_0
++ defaultEncoder = new Lazy <HttpEncoder> (() => new HttpEncoder ());
++ currentEncoderLazy = new Lazy <HttpEncoder> (new Func <HttpEncoder> (GetCustomEncoderFromConfig));
++#else
++ defaultEncoder = new HttpEncoder ();
++ currentEncoder = defaultEncoder;
++#endif
++ }
++
++ public HttpEncoder ()
++ {
++ }
++#if NET_4_0
++ protected internal virtual
++#else
++ internal static
++#endif
++ void HeaderNameValueEncode (string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue)
++ {
++ if (String.IsNullOrEmpty (headerName))
++ encodedHeaderName = headerName;
++ else
++ encodedHeaderName = EncodeHeaderString (headerName);
++
++ if (String.IsNullOrEmpty (headerValue))
++ encodedHeaderValue = headerValue;
++ else
++ encodedHeaderValue = EncodeHeaderString (headerValue);
++ }
++
++ static void StringBuilderAppend (string s, ref StringBuilder sb)
++ {
++ if (sb == null)
++ sb = new StringBuilder (s);
++ else
++ sb.Append (s);
++ }
++
++ static string EncodeHeaderString (string input)
++ {
++ StringBuilder sb = null;
++ char ch;
++
++ for (int i = 0; i < input.Length; i++) {
++ ch = input [i];
++
++ if ((ch < 32 && ch != 9) || ch == 127)
++ StringBuilderAppend (String.Format ("%{0:x2}", (int)ch), ref sb);
++ }
++
++ if (sb != null)
++ return sb.ToString ();
++
++ return input;
++ }
++#if NET_4_0
++ protected internal virtual void HtmlAttributeEncode (string value, TextWriter output)
++ {
++
++ if (output == null)
++ throw new ArgumentNullException ("output");
++
++ if (String.IsNullOrEmpty (value))
++ return;
++
++ output.Write (HtmlAttributeEncode (value));
++ }
++
++ protected internal virtual void HtmlDecode (string value, TextWriter output)
++ {
++ if (output == null)
++ throw new ArgumentNullException ("output");
++
++ output.Write (HtmlDecode (value));
++ }
++
++ protected internal virtual void HtmlEncode (string value, TextWriter output)
++ {
++ if (output == null)
++ throw new ArgumentNullException ("output");
++
++ output.Write (HtmlEncode (value));
++ }
++
++ protected internal virtual byte[] UrlEncode (byte[] bytes, int offset, int count)
++ {
++ return UrlEncodeToBytes (bytes, offset, count);
++ }
++
++ static HttpEncoder GetCustomEncoderFromConfig ()
++ {
++ var cfg = WebConfigurationManager.GetSection ("system.web/httpRuntime") as HttpRuntimeSection;
++ string typeName = cfg.EncoderType;
++
++ if (String.Compare (typeName, "System.Web.Util.HttpEncoder", StringComparison.OrdinalIgnoreCase) == 0)
++ return Default;
++
++ Type t = Type.GetType (typeName, false);
++ if (t == null)
++ throw new ConfigurationErrorsException (String.Format ("Could not load type '{0}'.", typeName));
++
++ if (!typeof (HttpEncoder).IsAssignableFrom (t))
++ throw new ConfigurationErrorsException (
++ String.Format ("'{0}' is not allowed here because it does not extend class 'System.Web.Util.HttpEncoder'.", typeName)
++ );
++
++ return Activator.CreateInstance (t, false) as HttpEncoder;
++ }
++#endif
++#if NET_4_0
++ protected internal virtual
++#else
++ internal static
++#endif
++ string UrlPathEncode (string value)
++ {
++ if (String.IsNullOrEmpty (value))
++ return value;
++
++ MemoryStream result = new MemoryStream ();
++ int length = value.Length;
++ for (int i = 0; i < length; i++)
++ UrlPathEncodeChar (value [i], result);
++
++ return Encoding.ASCII.GetString (result.ToArray ());
++ }
++
++ internal static byte[] UrlEncodeToBytes (byte[] bytes, int offset, int count)
++ {
++ if (bytes == null)
++ throw new ArgumentNullException ("bytes");
++
++ int blen = bytes.Length;
++ if (blen == 0)
++ return new byte [0];
++
++ if (offset < 0 || offset >= blen)
++ throw new ArgumentOutOfRangeException("offset");
++
++ if (count < 0 || count > blen - offset)
++ throw new ArgumentOutOfRangeException("count");
++
++ MemoryStream result = new MemoryStream (count);
++ int end = offset + count;
++ for (int i = offset; i < end; i++)
++ UrlEncodeChar ((char)bytes [i], result, false);
++
++ return result.ToArray();
++ }
++
++ internal static string HtmlEncode (string s)
++ {
++ if (s == null)
++ return null;
++
++ if (s.Length == 0)
++ return String.Empty;
++
++ bool needEncode = false;
++ for (int i = 0; i < s.Length; i++) {
++ char c = s [i];
++ if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
++#if NET_4_0
++ || c == '\''
++#endif
++ ) {
++ needEncode = true;
++ break;
++ }
++ }
++
++ if (!needEncode)
++ return s;
++
++ StringBuilder output = new StringBuilder ();
++ char ch;
++ int len = s.Length;
++
++ for (int i = 0; i < len; i++) {
++ switch (s [i]) {
++ case '&' :
++ output.Append ("&");
++ break;
++ case '>' :
++ output.Append (">");
++ break;
++ case '<' :
++ output.Append ("<");
++ break;
++ case '"' :
++ output.Append (""");
++ break;
++#if NET_4_0
++ case '\'':
++ output.Append ("'");
++ break;
++#endif
++ case '\uff1c':
++ output.Append ("<");
++ break;
++
++ case '\uff1e':
++ output.Append (">");
++ break;
++
++ default:
++ ch = s [i];
++ if (ch > 159 && ch < 256) {
++ output.Append ("&#");
++ output.Append (((int) ch).ToString (Helpers.InvariantCulture));
++ output.Append (";");
++ } else
++ output.Append (ch);
++ break;
++ }
++ }
++
++ return output.ToString ();
++ }
++
++ internal static string HtmlAttributeEncode (string s)
++ {
++#if NET_4_0
++ if (String.IsNullOrEmpty (s))
++ return String.Empty;
++#else
++ if (s == null)
++ return null;
++
++ if (s.Length == 0)
++ return String.Empty;
++#endif
++ bool needEncode = false;
++ for (int i = 0; i < s.Length; i++) {
++ char c = s [i];
++ if (c == '&' || c == '"' || c == '<'
++#if NET_4_0
++ || c == '\''
++#endif
++ ) {
++ needEncode = true;
++ break;
++ }
++ }
++
++ if (!needEncode)
++ return s;
++
++ StringBuilder output = new StringBuilder ();
++ int len = s.Length;
++ for (int i = 0; i < len; i++)
++ switch (s [i]) {
++ case '&' :
++ output.Append ("&");
++ break;
++ case '"' :
++ output.Append (""");
++ break;
++ case '<':
++ output.Append ("<");
++ break;
++#if NET_4_0
++ case '\'':
++ output.Append ("'");
++ break;
++#endif
++ default:
++ output.Append (s [i]);
++ break;
++ }
++
++ return output.ToString();
++ }
++
++ internal static string HtmlDecode (string s)
++ {
++ if (s == null)
++ return null;
++
++ if (s.Length == 0)
++ return String.Empty;
++
++ if (s.IndexOf ('&') == -1)
++ return s;
++#if NET_4_0
++ StringBuilder rawEntity = new StringBuilder ();
++#endif
++ StringBuilder entity = new StringBuilder ();
++ StringBuilder output = new StringBuilder ();
++ int len = s.Length;
++ // 0 -> nothing,
++ // 1 -> right after '&'
++ // 2 -> between '&' and ';' but no '#'
++ // 3 -> '#' found after '&' and getting numbers
++ int state = 0;
++ int number = 0;
++ bool is_hex_value = false;
++ bool have_trailing_digits = false;
++
++ for (int i = 0; i < len; i++) {
++ char c = s [i];
++ if (state == 0) {
++ if (c == '&') {
++ entity.Append (c);
++#if NET_4_0
++ rawEntity.Append (c);
++#endif
++ state = 1;
++ } else {
++ output.Append (c);
++ }
++ continue;
++ }
++
++ if (c == '&') {
++ state = 1;
++ if (have_trailing_digits) {
++ entity.Append (number.ToString (Helpers.InvariantCulture));
++ have_trailing_digits = false;
++ }
++
++ output.Append (entity.ToString ());
++ entity.Length = 0;
++ entity.Append ('&');
++ continue;
++ }
++
++ if (state == 1) {
++ if (c == ';') {
++ state = 0;
++ output.Append (entity.ToString ());
++ output.Append (c);
++ entity.Length = 0;
++ } else {
++ number = 0;
++ is_hex_value = false;
++ if (c != '#') {
++ state = 2;
++ } else {
++ state = 3;
++ }
++ entity.Append (c);
++#if NET_4_0
++ rawEntity.Append (c);
++#endif
++ }
++ } else if (state == 2) {
++ entity.Append (c);
++ if (c == ';') {
++ string key = entity.ToString ();
++ if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2)))
++ key = Entities [key.Substring (1, key.Length - 2)].ToString ();
++
++ output.Append (key);
++ state = 0;
++ entity.Length = 0;
++#if NET_4_0
++ rawEntity.Length = 0;
++#endif
++ }
++ } else if (state == 3) {
++ if (c == ';') {
++#if NET_4_0
++ if (number == 0)
++ output.Append (rawEntity.ToString () + ";");
++ else
++#endif
++ if (number > 65535) {
++ output.Append ("&#");
++ output.Append (number.ToString (Helpers.InvariantCulture));
++ output.Append (";");
++ } else {
++ output.Append ((char) number);
++ }
++ state = 0;
++ entity.Length = 0;
++#if NET_4_0
++ rawEntity.Length = 0;
++#endif
++ have_trailing_digits = false;
++ } else if (is_hex_value && Uri.IsHexDigit(c)) {
++ number = number * 16 + Uri.FromHex(c);
++ have_trailing_digits = true;
++#if NET_4_0
++ rawEntity.Append (c);
++#endif
++ } else if (Char.IsDigit (c)) {
++ number = number * 10 + ((int) c - '0');
++ have_trailing_digits = true;
++#if NET_4_0
++ rawEntity.Append (c);
++#endif
++ } else if (number == 0 && (c == 'x' || c == 'X')) {
++ is_hex_value = true;
++#if NET_4_0
++ rawEntity.Append (c);
++#endif
++ } else {
++ state = 2;
++ if (have_trailing_digits) {
++ entity.Append (number.ToString (Helpers.InvariantCulture));
++ have_trailing_digits = false;
++ }
++ entity.Append (c);
++ }
++ }
++ }
++
++ if (entity.Length > 0) {
++ output.Append (entity.ToString ());
++ } else if (have_trailing_digits) {
++ output.Append (number.ToString (Helpers.InvariantCulture));
++ }
++ return output.ToString ();
++ }
++
++ internal static bool NotEncoded (char c)
++ {
++ return (c == '!' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'
++#if !NET_4_0
++ || c == '\''
++#endif
++ );
++ }
++
++ internal static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
++ if (c > 255) {
++ //FIXME: what happens when there is an internal error?
++ //if (!isUnicode)
++ // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
++ int idx;
++ int i = (int) c;
++
++ result.WriteByte ((byte)'%');
++ result.WriteByte ((byte)'u');
++ idx = i >> 12;
++ result.WriteByte ((byte)hexChars [idx]);
++ idx = (i >> 8) & 0x0F;
++ result.WriteByte ((byte)hexChars [idx]);
++ idx = (i >> 4) & 0x0F;
++ result.WriteByte ((byte)hexChars [idx]);
++ idx = i & 0x0F;
++ result.WriteByte ((byte)hexChars [idx]);
++ return;
++ }
++
++ if (c > ' ' && NotEncoded (c)) {
++ result.WriteByte ((byte)c);
++ return;
++ }
++ if (c==' ') {
++ result.WriteByte ((byte)'+');
++ return;
++ }
++ if ( (c < '0') ||
++ (c < 'A' && c > '9') ||
++ (c > 'Z' && c < 'a') ||
++ (c > 'z')) {
++ if (isUnicode && c > 127) {
++ result.WriteByte ((byte)'%');
++ result.WriteByte ((byte)'u');
++ result.WriteByte ((byte)'0');
++ result.WriteByte ((byte)'0');
++ }
++ else
++ result.WriteByte ((byte)'%');
++
++ int idx = ((int) c) >> 4;
++ result.WriteByte ((byte)hexChars [idx]);
++ idx = ((int) c) & 0x0F;
++ result.WriteByte ((byte)hexChars [idx]);
++ }
++ else
++ result.WriteByte ((byte)c);
++ }
++
++ internal static void UrlPathEncodeChar (char c, Stream result)
++ {
++ if (c < 33 || c > 126) {
++ byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
++ for (int i = 0; i < bIn.Length; i++) {
++ result.WriteByte ((byte) '%');
++ int idx = ((int) bIn [i]) >> 4;
++ result.WriteByte ((byte) hexChars [idx]);
++ idx = ((int) bIn [i]) & 0x0F;
++ result.WriteByte ((byte) hexChars [idx]);
++ }
++ }
++ else if (c == ' ') {
++ result.WriteByte ((byte) '%');
++ result.WriteByte ((byte) '2');
++ result.WriteByte ((byte) '0');
++ }
++ else
++ result.WriteByte ((byte) c);
++ }
++
++ static void InitEntities ()
++ {
++ // Build the hash table of HTML entity references. This list comes
++ // from the HTML 4.01 W3C recommendation.
++ entities = new SortedDictionary <string, char> (StringComparer.Ordinal);
++
++ entities.Add ("nbsp", '\u00A0');
++ entities.Add ("iexcl", '\u00A1');
++ entities.Add ("cent", '\u00A2');
++ entities.Add ("pound", '\u00A3');
++ entities.Add ("curren", '\u00A4');
++ entities.Add ("yen", '\u00A5');
++ entities.Add ("brvbar", '\u00A6');
++ entities.Add ("sect", '\u00A7');
++ entities.Add ("uml", '\u00A8');
++ entities.Add ("copy", '\u00A9');
++ entities.Add ("ordf", '\u00AA');
++ entities.Add ("laquo", '\u00AB');
++ entities.Add ("not", '\u00AC');
++ entities.Add ("shy", '\u00AD');
++ entities.Add ("reg", '\u00AE');
++ entities.Add ("macr", '\u00AF');
++ entities.Add ("deg", '\u00B0');
++ entities.Add ("plusmn", '\u00B1');
++ entities.Add ("sup2", '\u00B2');
++ entities.Add ("sup3", '\u00B3');
++ entities.Add ("acute", '\u00B4');
++ entities.Add ("micro", '\u00B5');
++ entities.Add ("para", '\u00B6');
++ entities.Add ("middot", '\u00B7');
++ entities.Add ("cedil", '\u00B8');
++ entities.Add ("sup1", '\u00B9');
++ entities.Add ("ordm", '\u00BA');
++ entities.Add ("raquo", '\u00BB');
++ entities.Add ("frac14", '\u00BC');
++ entities.Add ("frac12", '\u00BD');
++ entities.Add ("frac34", '\u00BE');
++ entities.Add ("iquest", '\u00BF');
++ entities.Add ("Agrave", '\u00C0');
++ entities.Add ("Aacute", '\u00C1');
++ entities.Add ("Acirc", '\u00C2');
++ entities.Add ("Atilde", '\u00C3');
++ entities.Add ("Auml", '\u00C4');
++ entities.Add ("Aring", '\u00C5');
++ entities.Add ("AElig", '\u00C6');
++ entities.Add ("Ccedil", '\u00C7');
++ entities.Add ("Egrave", '\u00C8');
++ entities.Add ("Eacute", '\u00C9');
++ entities.Add ("Ecirc", '\u00CA');
++ entities.Add ("Euml", '\u00CB');
++ entities.Add ("Igrave", '\u00CC');
++ entities.Add ("Iacute", '\u00CD');
++ entities.Add ("Icirc", '\u00CE');
++ entities.Add ("Iuml", '\u00CF');
++ entities.Add ("ETH", '\u00D0');
++ entities.Add ("Ntilde", '\u00D1');
++ entities.Add ("Ograve", '\u00D2');
++ entities.Add ("Oacute", '\u00D3');
++ entities.Add ("Ocirc", '\u00D4');
++ entities.Add ("Otilde", '\u00D5');
++ entities.Add ("Ouml", '\u00D6');
++ entities.Add ("times", '\u00D7');
++ entities.Add ("Oslash", '\u00D8');
++ entities.Add ("Ugrave", '\u00D9');
++ entities.Add ("Uacute", '\u00DA');
++ entities.Add ("Ucirc", '\u00DB');
++ entities.Add ("Uuml", '\u00DC');
++ entities.Add ("Yacute", '\u00DD');
++ entities.Add ("THORN", '\u00DE');
++ entities.Add ("szlig", '\u00DF');
++ entities.Add ("agrave", '\u00E0');
++ entities.Add ("aacute", '\u00E1');
++ entities.Add ("acirc", '\u00E2');
++ entities.Add ("atilde", '\u00E3');
++ entities.Add ("auml", '\u00E4');
++ entities.Add ("aring", '\u00E5');
++ entities.Add ("aelig", '\u00E6');
++ entities.Add ("ccedil", '\u00E7');
++ entities.Add ("egrave", '\u00E8');
++ entities.Add ("eacute", '\u00E9');
++ entities.Add ("ecirc", '\u00EA');
++ entities.Add ("euml", '\u00EB');
++ entities.Add ("igrave", '\u00EC');
++ entities.Add ("iacute", '\u00ED');
++ entities.Add ("icirc", '\u00EE');
++ entities.Add ("iuml", '\u00EF');
++ entities.Add ("eth", '\u00F0');
++ entities.Add ("ntilde", '\u00F1');
++ entities.Add ("ograve", '\u00F2');
++ entities.Add ("oacute", '\u00F3');
++ entities.Add ("ocirc", '\u00F4');
++ entities.Add ("otilde", '\u00F5');
++ entities.Add ("ouml", '\u00F6');
++ entities.Add ("divide", '\u00F7');
++ entities.Add ("oslash", '\u00F8');
++ entities.Add ("ugrave", '\u00F9');
++ entities.Add ("uacute", '\u00FA');
++ entities.Add ("ucirc", '\u00FB');
++ entities.Add ("uuml", '\u00FC');
++ entities.Add ("yacute", '\u00FD');
++ entities.Add ("thorn", '\u00FE');
++ entities.Add ("yuml", '\u00FF');
++ entities.Add ("fnof", '\u0192');
++ entities.Add ("Alpha", '\u0391');
++ entities.Add ("Beta", '\u0392');
++ entities.Add ("Gamma", '\u0393');
++ entities.Add ("Delta", '\u0394');
++ entities.Add ("Epsilon", '\u0395');
++ entities.Add ("Zeta", '\u0396');
++ entities.Add ("Eta", '\u0397');
++ entities.Add ("Theta", '\u0398');
++ entities.Add ("Iota", '\u0399');
++ entities.Add ("Kappa", '\u039A');
++ entities.Add ("Lambda", '\u039B');
++ entities.Add ("Mu", '\u039C');
++ entities.Add ("Nu", '\u039D');
++ entities.Add ("Xi", '\u039E');
++ entities.Add ("Omicron", '\u039F');
++ entities.Add ("Pi", '\u03A0');
++ entities.Add ("Rho", '\u03A1');
++ entities.Add ("Sigma", '\u03A3');
++ entities.Add ("Tau", '\u03A4');
++ entities.Add ("Upsilon", '\u03A5');
++ entities.Add ("Phi", '\u03A6');
++ entities.Add ("Chi", '\u03A7');
++ entities.Add ("Psi", '\u03A8');
++ entities.Add ("Omega", '\u03A9');
++ entities.Add ("alpha", '\u03B1');
++ entities.Add ("beta", '\u03B2');
++ entities.Add ("gamma", '\u03B3');
++ entities.Add ("delta", '\u03B4');
++ entities.Add ("epsilon", '\u03B5');
++ entities.Add ("zeta", '\u03B6');
++ entities.Add ("eta", '\u03B7');
++ entities.Add ("theta", '\u03B8');
++ entities.Add ("iota", '\u03B9');
++ entities.Add ("kappa", '\u03BA');
++ entities.Add ("lambda", '\u03BB');
++ entities.Add ("mu", '\u03BC');
++ entities.Add ("nu", '\u03BD');
++ entities.Add ("xi", '\u03BE');
++ entities.Add ("omicron", '\u03BF');
++ entities.Add ("pi", '\u03C0');
++ entities.Add ("rho", '\u03C1');
++ entities.Add ("sigmaf", '\u03C2');
++ entities.Add ("sigma", '\u03C3');
++ entities.Add ("tau", '\u03C4');
++ entities.Add ("upsilon", '\u03C5');
++ entities.Add ("phi", '\u03C6');
++ entities.Add ("chi", '\u03C7');
++ entities.Add ("psi", '\u03C8');
++ entities.Add ("omega", '\u03C9');
++ entities.Add ("thetasym", '\u03D1');
++ entities.Add ("upsih", '\u03D2');
++ entities.Add ("piv", '\u03D6');
++ entities.Add ("bull", '\u2022');
++ entities.Add ("hellip", '\u2026');
++ entities.Add ("prime", '\u2032');
++ entities.Add ("Prime", '\u2033');
++ entities.Add ("oline", '\u203E');
++ entities.Add ("frasl", '\u2044');
++ entities.Add ("weierp", '\u2118');
++ entities.Add ("image", '\u2111');
++ entities.Add ("real", '\u211C');
++ entities.Add ("trade", '\u2122');
++ entities.Add ("alefsym", '\u2135');
++ entities.Add ("larr", '\u2190');
++ entities.Add ("uarr", '\u2191');
++ entities.Add ("rarr", '\u2192');
++ entities.Add ("darr", '\u2193');
++ entities.Add ("harr", '\u2194');
++ entities.Add ("crarr", '\u21B5');
++ entities.Add ("lArr", '\u21D0');
++ entities.Add ("uArr", '\u21D1');
++ entities.Add ("rArr", '\u21D2');
++ entities.Add ("dArr", '\u21D3');
++ entities.Add ("hArr", '\u21D4');
++ entities.Add ("forall", '\u2200');
++ entities.Add ("part", '\u2202');
++ entities.Add ("exist", '\u2203');
++ entities.Add ("empty", '\u2205');
++ entities.Add ("nabla", '\u2207');
++ entities.Add ("isin", '\u2208');
++ entities.Add ("notin", '\u2209');
++ entities.Add ("ni", '\u220B');
++ entities.Add ("prod", '\u220F');
++ entities.Add ("sum", '\u2211');
++ entities.Add ("minus", '\u2212');
++ entities.Add ("lowast", '\u2217');
++ entities.Add ("radic", '\u221A');
++ entities.Add ("prop", '\u221D');
++ entities.Add ("infin", '\u221E');
++ entities.Add ("ang", '\u2220');
++ entities.Add ("and", '\u2227');
++ entities.Add ("or", '\u2228');
++ entities.Add ("cap", '\u2229');
++ entities.Add ("cup", '\u222A');
++ entities.Add ("int", '\u222B');
++ entities.Add ("there4", '\u2234');
++ entities.Add ("sim", '\u223C');
++ entities.Add ("cong", '\u2245');
++ entities.Add ("asymp", '\u2248');
++ entities.Add ("ne", '\u2260');
++ entities.Add ("equiv", '\u2261');
++ entities.Add ("le", '\u2264');
++ entities.Add ("ge", '\u2265');
++ entities.Add ("sub", '\u2282');
++ entities.Add ("sup", '\u2283');
++ entities.Add ("nsub", '\u2284');
++ entities.Add ("sube", '\u2286');
++ entities.Add ("supe", '\u2287');
++ entities.Add ("oplus", '\u2295');
++ entities.Add ("otimes", '\u2297');
++ entities.Add ("perp", '\u22A5');
++ entities.Add ("sdot", '\u22C5');
++ entities.Add ("lceil", '\u2308');
++ entities.Add ("rceil", '\u2309');
++ entities.Add ("lfloor", '\u230A');
++ entities.Add ("rfloor", '\u230B');
++ entities.Add ("lang", '\u2329');
++ entities.Add ("rang", '\u232A');
++ entities.Add ("loz", '\u25CA');
++ entities.Add ("spades", '\u2660');
++ entities.Add ("clubs", '\u2663');
++ entities.Add ("hearts", '\u2665');
++ entities.Add ("diams", '\u2666');
++ entities.Add ("quot", '\u0022');
++ entities.Add ("amp", '\u0026');
++ entities.Add ("lt", '\u003C');
++ entities.Add ("gt", '\u003E');
++ entities.Add ("OElig", '\u0152');
++ entities.Add ("oelig", '\u0153');
++ entities.Add ("Scaron", '\u0160');
++ entities.Add ("scaron", '\u0161');
++ entities.Add ("Yuml", '\u0178');
++ entities.Add ("circ", '\u02C6');
++ entities.Add ("tilde", '\u02DC');
++ entities.Add ("ensp", '\u2002');
++ entities.Add ("emsp", '\u2003');
++ entities.Add ("thinsp", '\u2009');
++ entities.Add ("zwnj", '\u200C');
++ entities.Add ("zwj", '\u200D');
++ entities.Add ("lrm", '\u200E');
++ entities.Add ("rlm", '\u200F');
++ entities.Add ("ndash", '\u2013');
++ entities.Add ("mdash", '\u2014');
++ entities.Add ("lsquo", '\u2018');
++ entities.Add ("rsquo", '\u2019');
++ entities.Add ("sbquo", '\u201A');
++ entities.Add ("ldquo", '\u201C');
++ entities.Add ("rdquo", '\u201D');
++ entities.Add ("bdquo", '\u201E');
++ entities.Add ("dagger", '\u2020');
++ entities.Add ("Dagger", '\u2021');
++ entities.Add ("permil", '\u2030');
++ entities.Add ("lsaquo", '\u2039');
++ entities.Add ("rsaquo", '\u203A');
++ entities.Add ("euro", '\u20AC');
++ }
++ }
++}
System.Web/HttpException.cs
System.Web/HttpFileCollection.cs
System.Web/HttpForbiddenHandler.cs
++System.Web/HttpHeaderCollection.cs
System.Web/HttpMethodNotAllowedHandler.cs
System.Web/HttpModuleCollection.cs
System.Web/HttpParamsCollection.cs
System.Web.Util/DataSourceResolver.cs
System.Web.Util/FileUtils.cs
System.Web.Util/Helpers.cs
++System.Web.Util/HttpEncoder.cs
System.Web.Util/ICalls.cs
System.Web.Util/IWebObjectFactory.cs
System.Web.Util/IWebPropertyAccessor.cs
++2010-06-01 Marek Habersack <mhabersack@novell.com>
++
++ * HttpUtility.cs: moved chunks of code to the new
++ System.Web.Util.HttpEncoder class.
++
++ * HttpResponseHeader.cs: encode header names and values using
++ HttpEncoder.
++
++ * HttpRequest.cs: added internal method Validate, to validate the
++ request in 4.0 profile.
++
++ * HttpHeaderCollection.cs: added. A helper class to encode header
++ names/values on add.
++
++ * HttpApplication.cs: Pipeline () validates request by calling
++ HttpRequest.Validate in the 4.0 profile.
++
2010-05-17 Marek Habersack <mhabersack@novell.com>
* HttpApplicationFactory.cs: pre-application start methods must be
Delegate eventHandler;
if (stop_processing)
yield return true;
--
#if NET_4_0
-- if (HttpRequest.ValidateRequestNewMode) {
-- char[] invalidChars = HttpRequest.RequestPathInvalidCharacters;
-- HttpRequest req = context.Request;
-- if (invalidChars != null && req != null) {
-- string path = req.PathNoValidation;
-- int idx = path != null ? path.IndexOfAny (invalidChars) : -1;
-- if (idx != -1)
-- throw HttpException.NewWithCode (
-- String.Format ("A potentially dangerous Request.Path value was detected from the client ({0}).", path [idx]),
-- WebEventCodes.RuntimeErrorValidationFailure
-- );
-- }
-- }
++ HttpRequest req = context.Request;
++ if (req != null)
++ req.Validate ();
#endif
context.MapRequestHandlerDone = false;
StartTimer ("BeginRequest");
--- /dev/null
--- /dev/null
++//
++// Authors:
++// Marek Habersack <mhabersack@novell.com>
++//
++// Copyright (C) 2010 Novell, Inc (http://www.novell.com)
++//
++// 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;
++using System.Collections.Specialized;
++using System.Web.Configuration;
++using System.Web.Util;
++
++namespace System.Web
++{
++ sealed class HttpHeaderCollection : NameValueCollection
++ {
++ bool? headerCheckingEnabled;
++
++ bool HeaderCheckingEnabled {
++ get {
++ if (headerCheckingEnabled == null) {
++ var cfg = WebConfigurationManager.GetSection ("system.web/httpRuntime") as HttpRuntimeSection;
++ headerCheckingEnabled = cfg.EnableHeaderChecking;
++ }
++
++ return (bool)headerCheckingEnabled;
++ }
++ }
++
++ public override void Add (string name, string value)
++ {
++ EncodeAndSetHeader (name, value, false);
++ }
++
++ public override void Set (string name, string value)
++ {
++ EncodeAndSetHeader (name, value, true);
++ }
++
++ void EncodeAndSetHeader (string name, string value, bool replaceExisting)
++ {
++ if (String.IsNullOrEmpty (name) || String.IsNullOrEmpty (value))
++ return;
++
++ string encName, encValue;
++ if (HeaderCheckingEnabled) {
++#if NET_4_0
++ HttpEncoder.Current.HeaderNameValueEncode (name, value, out encName, out encValue);
++#else
++ HttpEncoder.HeaderNameValueEncode (name, value, out encName, out encValue);
++#endif
++ } else {
++ encName = name;
++ encValue = value;
++ }
++
++ if (replaceExisting)
++ base.Set (encName, encValue);
++ else
++ base.Add (encName, encValue);
++ }
++ }
++}
validate_query_string = true;
validate_form = true;
}
--
++#if NET_4_0
++ internal void Validate ()
++ {
++ var cfg = WebConfigurationManager.GetSection ("system.web/httpRuntime") as HttpRuntimeSection;
++ string query = UrlComponents.Query;
++
++ if (query != null && query.Length > cfg.MaxQueryStringLength)
++ throw new HttpException (400, "The length of the query string for this request exceeds the configured maxQueryStringLength value.");
++
++ string path = PathNoValidation;
++ if (path != null) {
++ if (path.Length > cfg.MaxUrlLength)
++ throw new HttpException (400, "The length of the URL for this request exceeds the configured maxUrlLength value.");
++
++ char[] invalidChars = RequestPathInvalidCharacters;
++ if (invalidChars != null) {
++ int idx = path.IndexOfAny (invalidChars);
++ if (idx != -1)
++ throw HttpException.NewWithCode (
++ String.Format ("A potentially dangerous Request.Path value was detected from the client ({0}).", path [idx]),
++ WebEventCodes.RuntimeErrorValidationFailure
++ );
++ }
++ }
++ }
++#endif
#region internal routines
internal string ClientTarget {
get {
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
// Marek Habersack <mhabersack@novell.com>
//
--// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
++// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// the headers that we compute here.
//
-- NameValueCollection headers;
++ HttpHeaderCollection headers;
bool headers_sent;
NameValueCollection cached_headers;
public NameValueCollection Headers {
get {
if (headers == null)
-- headers = new NameValueCollection ();
++ headers = new HttpHeaderCollection ();
return headers;
}
public void AppendHeader (string name, string value)
{
if (headers_sent)
-- throw new HttpException ("headers have been already sent");
--
++ throw new HttpException ("Headers have been already sent");
#if !TARGET_J2EE
if (String.Compare (name, "content-length", true, Helpers.InvariantCulture) == 0){
content_length = (long) UInt64.Parse (value);
//
//
--// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
++// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using System.Collections;
using System.Text;
using System.Web.Configuration;
++using System.Web.Util;
namespace System.Web
{
public string Value {
get { return headerValue; }
-- set { headerValue = EncodeHeader (value); }
++ set {
++ string hname, hvalue;
++#if NET_4_0
++ HttpEncoder.Current.HeaderNameValueEncode (null, value, out hname, out hvalue);
++#else
++ HttpEncoder.HeaderNameValueEncode (null, value, out hname, out hvalue);
++#endif
++ headerValue = hvalue;
++ }
}
static bool headerCheckingEnabled;
{
Value = val;
}
--
-- string EncodeHeader (string value)
-- {
-- if (value == null || value.Length == 0)
-- return value;
--
-- if (headerCheckingEnabled) {
-- StringBuilder ret = new StringBuilder ();
-- int len = value.Length;
--
-- for (int i = 0; i < len; i++) {
-- switch (value [i]) {
-- case '\r':
-- ret.Append ("%0d");
-- break;
--
-- case '\n':
-- ret.Append ("%0a");
-- break;
--
-- default:
-- ret.Append (value [i]);
-- break;
-- }
-- }
--
-- return ret.ToString ();
-- } else
-- return value;
-- }
internal abstract void SendContent (HttpWorkerRequest wr);
}
-- internal sealed class KnownResponseHeader : BaseResponseHeader {
++ internal sealed class KnownResponseHeader : BaseResponseHeader
++ {
public int ID;
internal KnownResponseHeader (int ID, string val) : base (val)
}
}
-- internal class UnknownResponseHeader : BaseResponseHeader {
-- public string Name;
++ internal sealed class UnknownResponseHeader : BaseResponseHeader
++ {
++ string headerName;
++
++ public string Name {
++ get { return headerName; }
++ set {
++ string hname, hvalue;
++#if NET_4_0
++ HttpEncoder.Current.HeaderNameValueEncode (value, null, out hname, out hvalue);
++#else
++ HttpEncoder.HeaderNameValueEncode (value, null, out hname, out hvalue);
++#endif
++ headerName = hname;
++ }
++ }
++
public UnknownResponseHeader (string name, string val) : base (val)
{
// Tim Coleman (tim@timcoleman.com)
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
//
--// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
++// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
return sb.ToString ();
}
}
-- #region Fields
--
-- static Hashtable entities;
-- static object lock_ = new object ();
--
-- #endregion // Fields
--
-- static Hashtable Entities {
-- get {
-- lock (lock_) {
-- if (entities == null)
-- InitEntities ();
--
-- return entities;
-- }
-- }
-- }
#region Constructors
-- static void InitEntities ()
-- {
-- // Build the hash table of HTML entity references. This list comes
-- // from the HTML 4.01 W3C recommendation.
-- entities = new Hashtable ();
-- entities.Add ("nbsp", '\u00A0');
-- entities.Add ("iexcl", '\u00A1');
-- entities.Add ("cent", '\u00A2');
-- entities.Add ("pound", '\u00A3');
-- entities.Add ("curren", '\u00A4');
-- entities.Add ("yen", '\u00A5');
-- entities.Add ("brvbar", '\u00A6');
-- entities.Add ("sect", '\u00A7');
-- entities.Add ("uml", '\u00A8');
-- entities.Add ("copy", '\u00A9');
-- entities.Add ("ordf", '\u00AA');
-- entities.Add ("laquo", '\u00AB');
-- entities.Add ("not", '\u00AC');
-- entities.Add ("shy", '\u00AD');
-- entities.Add ("reg", '\u00AE');
-- entities.Add ("macr", '\u00AF');
-- entities.Add ("deg", '\u00B0');
-- entities.Add ("plusmn", '\u00B1');
-- entities.Add ("sup2", '\u00B2');
-- entities.Add ("sup3", '\u00B3');
-- entities.Add ("acute", '\u00B4');
-- entities.Add ("micro", '\u00B5');
-- entities.Add ("para", '\u00B6');
-- entities.Add ("middot", '\u00B7');
-- entities.Add ("cedil", '\u00B8');
-- entities.Add ("sup1", '\u00B9');
-- entities.Add ("ordm", '\u00BA');
-- entities.Add ("raquo", '\u00BB');
-- entities.Add ("frac14", '\u00BC');
-- entities.Add ("frac12", '\u00BD');
-- entities.Add ("frac34", '\u00BE');
-- entities.Add ("iquest", '\u00BF');
-- entities.Add ("Agrave", '\u00C0');
-- entities.Add ("Aacute", '\u00C1');
-- entities.Add ("Acirc", '\u00C2');
-- entities.Add ("Atilde", '\u00C3');
-- entities.Add ("Auml", '\u00C4');
-- entities.Add ("Aring", '\u00C5');
-- entities.Add ("AElig", '\u00C6');
-- entities.Add ("Ccedil", '\u00C7');
-- entities.Add ("Egrave", '\u00C8');
-- entities.Add ("Eacute", '\u00C9');
-- entities.Add ("Ecirc", '\u00CA');
-- entities.Add ("Euml", '\u00CB');
-- entities.Add ("Igrave", '\u00CC');
-- entities.Add ("Iacute", '\u00CD');
-- entities.Add ("Icirc", '\u00CE');
-- entities.Add ("Iuml", '\u00CF');
-- entities.Add ("ETH", '\u00D0');
-- entities.Add ("Ntilde", '\u00D1');
-- entities.Add ("Ograve", '\u00D2');
-- entities.Add ("Oacute", '\u00D3');
-- entities.Add ("Ocirc", '\u00D4');
-- entities.Add ("Otilde", '\u00D5');
-- entities.Add ("Ouml", '\u00D6');
-- entities.Add ("times", '\u00D7');
-- entities.Add ("Oslash", '\u00D8');
-- entities.Add ("Ugrave", '\u00D9');
-- entities.Add ("Uacute", '\u00DA');
-- entities.Add ("Ucirc", '\u00DB');
-- entities.Add ("Uuml", '\u00DC');
-- entities.Add ("Yacute", '\u00DD');
-- entities.Add ("THORN", '\u00DE');
-- entities.Add ("szlig", '\u00DF');
-- entities.Add ("agrave", '\u00E0');
-- entities.Add ("aacute", '\u00E1');
-- entities.Add ("acirc", '\u00E2');
-- entities.Add ("atilde", '\u00E3');
-- entities.Add ("auml", '\u00E4');
-- entities.Add ("aring", '\u00E5');
-- entities.Add ("aelig", '\u00E6');
-- entities.Add ("ccedil", '\u00E7');
-- entities.Add ("egrave", '\u00E8');
-- entities.Add ("eacute", '\u00E9');
-- entities.Add ("ecirc", '\u00EA');
-- entities.Add ("euml", '\u00EB');
-- entities.Add ("igrave", '\u00EC');
-- entities.Add ("iacute", '\u00ED');
-- entities.Add ("icirc", '\u00EE');
-- entities.Add ("iuml", '\u00EF');
-- entities.Add ("eth", '\u00F0');
-- entities.Add ("ntilde", '\u00F1');
-- entities.Add ("ograve", '\u00F2');
-- entities.Add ("oacute", '\u00F3');
-- entities.Add ("ocirc", '\u00F4');
-- entities.Add ("otilde", '\u00F5');
-- entities.Add ("ouml", '\u00F6');
-- entities.Add ("divide", '\u00F7');
-- entities.Add ("oslash", '\u00F8');
-- entities.Add ("ugrave", '\u00F9');
-- entities.Add ("uacute", '\u00FA');
-- entities.Add ("ucirc", '\u00FB');
-- entities.Add ("uuml", '\u00FC');
-- entities.Add ("yacute", '\u00FD');
-- entities.Add ("thorn", '\u00FE');
-- entities.Add ("yuml", '\u00FF');
-- entities.Add ("fnof", '\u0192');
-- entities.Add ("Alpha", '\u0391');
-- entities.Add ("Beta", '\u0392');
-- entities.Add ("Gamma", '\u0393');
-- entities.Add ("Delta", '\u0394');
-- entities.Add ("Epsilon", '\u0395');
-- entities.Add ("Zeta", '\u0396');
-- entities.Add ("Eta", '\u0397');
-- entities.Add ("Theta", '\u0398');
-- entities.Add ("Iota", '\u0399');
-- entities.Add ("Kappa", '\u039A');
-- entities.Add ("Lambda", '\u039B');
-- entities.Add ("Mu", '\u039C');
-- entities.Add ("Nu", '\u039D');
-- entities.Add ("Xi", '\u039E');
-- entities.Add ("Omicron", '\u039F');
-- entities.Add ("Pi", '\u03A0');
-- entities.Add ("Rho", '\u03A1');
-- entities.Add ("Sigma", '\u03A3');
-- entities.Add ("Tau", '\u03A4');
-- entities.Add ("Upsilon", '\u03A5');
-- entities.Add ("Phi", '\u03A6');
-- entities.Add ("Chi", '\u03A7');
-- entities.Add ("Psi", '\u03A8');
-- entities.Add ("Omega", '\u03A9');
-- entities.Add ("alpha", '\u03B1');
-- entities.Add ("beta", '\u03B2');
-- entities.Add ("gamma", '\u03B3');
-- entities.Add ("delta", '\u03B4');
-- entities.Add ("epsilon", '\u03B5');
-- entities.Add ("zeta", '\u03B6');
-- entities.Add ("eta", '\u03B7');
-- entities.Add ("theta", '\u03B8');
-- entities.Add ("iota", '\u03B9');
-- entities.Add ("kappa", '\u03BA');
-- entities.Add ("lambda", '\u03BB');
-- entities.Add ("mu", '\u03BC');
-- entities.Add ("nu", '\u03BD');
-- entities.Add ("xi", '\u03BE');
-- entities.Add ("omicron", '\u03BF');
-- entities.Add ("pi", '\u03C0');
-- entities.Add ("rho", '\u03C1');
-- entities.Add ("sigmaf", '\u03C2');
-- entities.Add ("sigma", '\u03C3');
-- entities.Add ("tau", '\u03C4');
-- entities.Add ("upsilon", '\u03C5');
-- entities.Add ("phi", '\u03C6');
-- entities.Add ("chi", '\u03C7');
-- entities.Add ("psi", '\u03C8');
-- entities.Add ("omega", '\u03C9');
-- entities.Add ("thetasym", '\u03D1');
-- entities.Add ("upsih", '\u03D2');
-- entities.Add ("piv", '\u03D6');
-- entities.Add ("bull", '\u2022');
-- entities.Add ("hellip", '\u2026');
-- entities.Add ("prime", '\u2032');
-- entities.Add ("Prime", '\u2033');
-- entities.Add ("oline", '\u203E');
-- entities.Add ("frasl", '\u2044');
-- entities.Add ("weierp", '\u2118');
-- entities.Add ("image", '\u2111');
-- entities.Add ("real", '\u211C');
-- entities.Add ("trade", '\u2122');
-- entities.Add ("alefsym", '\u2135');
-- entities.Add ("larr", '\u2190');
-- entities.Add ("uarr", '\u2191');
-- entities.Add ("rarr", '\u2192');
-- entities.Add ("darr", '\u2193');
-- entities.Add ("harr", '\u2194');
-- entities.Add ("crarr", '\u21B5');
-- entities.Add ("lArr", '\u21D0');
-- entities.Add ("uArr", '\u21D1');
-- entities.Add ("rArr", '\u21D2');
-- entities.Add ("dArr", '\u21D3');
-- entities.Add ("hArr", '\u21D4');
-- entities.Add ("forall", '\u2200');
-- entities.Add ("part", '\u2202');
-- entities.Add ("exist", '\u2203');
-- entities.Add ("empty", '\u2205');
-- entities.Add ("nabla", '\u2207');
-- entities.Add ("isin", '\u2208');
-- entities.Add ("notin", '\u2209');
-- entities.Add ("ni", '\u220B');
-- entities.Add ("prod", '\u220F');
-- entities.Add ("sum", '\u2211');
-- entities.Add ("minus", '\u2212');
-- entities.Add ("lowast", '\u2217');
-- entities.Add ("radic", '\u221A');
-- entities.Add ("prop", '\u221D');
-- entities.Add ("infin", '\u221E');
-- entities.Add ("ang", '\u2220');
-- entities.Add ("and", '\u2227');
-- entities.Add ("or", '\u2228');
-- entities.Add ("cap", '\u2229');
-- entities.Add ("cup", '\u222A');
-- entities.Add ("int", '\u222B');
-- entities.Add ("there4", '\u2234');
-- entities.Add ("sim", '\u223C');
-- entities.Add ("cong", '\u2245');
-- entities.Add ("asymp", '\u2248');
-- entities.Add ("ne", '\u2260');
-- entities.Add ("equiv", '\u2261');
-- entities.Add ("le", '\u2264');
-- entities.Add ("ge", '\u2265');
-- entities.Add ("sub", '\u2282');
-- entities.Add ("sup", '\u2283');
-- entities.Add ("nsub", '\u2284');
-- entities.Add ("sube", '\u2286');
-- entities.Add ("supe", '\u2287');
-- entities.Add ("oplus", '\u2295');
-- entities.Add ("otimes", '\u2297');
-- entities.Add ("perp", '\u22A5');
-- entities.Add ("sdot", '\u22C5');
-- entities.Add ("lceil", '\u2308');
-- entities.Add ("rceil", '\u2309');
-- entities.Add ("lfloor", '\u230A');
-- entities.Add ("rfloor", '\u230B');
-- entities.Add ("lang", '\u2329');
-- entities.Add ("rang", '\u232A');
-- entities.Add ("loz", '\u25CA');
-- entities.Add ("spades", '\u2660');
-- entities.Add ("clubs", '\u2663');
-- entities.Add ("hearts", '\u2665');
-- entities.Add ("diams", '\u2666');
-- entities.Add ("quot", '\u0022');
-- entities.Add ("amp", '\u0026');
-- entities.Add ("lt", '\u003C');
-- entities.Add ("gt", '\u003E');
-- entities.Add ("OElig", '\u0152');
-- entities.Add ("oelig", '\u0153');
-- entities.Add ("Scaron", '\u0160');
-- entities.Add ("scaron", '\u0161');
-- entities.Add ("Yuml", '\u0178');
-- entities.Add ("circ", '\u02C6');
-- entities.Add ("tilde", '\u02DC');
-- entities.Add ("ensp", '\u2002');
-- entities.Add ("emsp", '\u2003');
-- entities.Add ("thinsp", '\u2009');
-- entities.Add ("zwnj", '\u200C');
-- entities.Add ("zwj", '\u200D');
-- entities.Add ("lrm", '\u200E');
-- entities.Add ("rlm", '\u200F');
-- entities.Add ("ndash", '\u2013');
-- entities.Add ("mdash", '\u2014');
-- entities.Add ("lsquo", '\u2018');
-- entities.Add ("rsquo", '\u2019');
-- entities.Add ("sbquo", '\u201A');
-- entities.Add ("ldquo", '\u201C');
-- entities.Add ("rdquo", '\u201D');
-- entities.Add ("bdquo", '\u201E');
-- entities.Add ("dagger", '\u2020');
-- entities.Add ("Dagger", '\u2021');
-- entities.Add ("permil", '\u2030');
-- entities.Add ("lsaquo", '\u2039');
-- entities.Add ("rsaquo", '\u203A');
-- entities.Add ("euro", '\u20AC');
-- }
--
public HttpUtility ()
{
}
public static void HtmlAttributeEncode (string s, TextWriter output)
{
-- output.Write(HtmlAttributeEncode(s));
++ if (output == null) {
++#if NET_4_0
++ throw new ArgumentNullException ("output");
++#else
++ throw new NullReferenceException (".NET emulation");
++#endif
++ }
++#if NET_4_0
++ HttpEncoder.Current.HtmlAttributeEncode (s, output);
++#else
++ output.Write (HttpEncoder.HtmlAttributeEncode (s));
++#endif
}
public static string HtmlAttributeEncode (string s)
{
-- if (null == s)
-- return null;
--
-- bool needEncode = false;
-- for (int i = 0; i < s.Length; i++) {
-- char c = s [i];
-- if (c == '&' || c == '"' || c == '<'
#if NET_4_0
-- || c == '\''
--#endif
-- ) {
-- needEncode = true;
-- break;
-- }
++ if (s == null)
++ return null;
++
++ using (var sw = new StringWriter ()) {
++ HttpEncoder.Current.HtmlAttributeEncode (s, sw);
++ return sw.ToString ();
}
--
-- if (!needEncode)
-- return s;
--
-- StringBuilder output = new StringBuilder ();
-- int len = s.Length;
-- for (int i = 0; i < len; i++)
-- switch (s [i]) {
-- case '&' :
-- output.Append ("&");
-- break;
-- case '"' :
-- output.Append (""");
-- break;
-- case '<':
-- output.Append ("<");
-- break;
--#if NET_4_0
-- case '\'':
-- output.Append ("'");
-- break;
++#else
++ return HttpEncoder.HtmlAttributeEncode (s);
#endif
-- default:
-- output.Append (s [i]);
-- break;
-- }
--
-- return output.ToString();
}
public static string UrlDecode (string str)
for (int i = 0; i < len; i++) {
char c = s [i];
if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) {
-- if (NotEncoded (c))
++ if (HttpEncoder.NotEncoded (c))
continue;
needEncode = true;
return null;
if (bytes.Length == 0)
-- return "";
++ return String.Empty;
return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, bytes.Length));
}
return null;
if (bytes.Length == 0)
-- return "";
++ return String.Empty;
return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, offset, count));
}
if (str == null)
return null;
-- if (str == "")
++ if (str.Length == 0)
return new byte [0];
byte [] bytes = e.GetBytes (str);
return UrlEncodeToBytes (bytes, 0, bytes.Length);
}
-- static char [] hexChars = "0123456789abcdef".ToCharArray ();
--
-- static bool NotEncoded (char c)
-- {
-- return (c == '!' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'
--#if !NET_4_0
-- || c == '\''
--#endif
-- );
-- }
--
-- static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
-- if (c > 255) {
-- //FIXME: what happens when there is an internal error?
-- //if (!isUnicode)
-- // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
-- int idx;
-- int i = (int) c;
--
-- result.WriteByte ((byte)'%');
-- result.WriteByte ((byte)'u');
-- idx = i >> 12;
-- result.WriteByte ((byte)hexChars [idx]);
-- idx = (i >> 8) & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
-- idx = (i >> 4) & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
-- idx = i & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
-- return;
-- }
--
-- if (c > ' ' && NotEncoded (c)) {
-- result.WriteByte ((byte)c);
-- return;
-- }
-- if (c==' ') {
-- result.WriteByte ((byte)'+');
-- return;
-- }
-- if ( (c < '0') ||
-- (c < 'A' && c > '9') ||
-- (c > 'Z' && c < 'a') ||
-- (c > 'z')) {
-- if (isUnicode && c > 127) {
-- result.WriteByte ((byte)'%');
-- result.WriteByte ((byte)'u');
-- result.WriteByte ((byte)'0');
-- result.WriteByte ((byte)'0');
-- }
-- else
-- result.WriteByte ((byte)'%');
--
-- int idx = ((int) c) >> 4;
-- result.WriteByte ((byte)hexChars [idx]);
-- idx = ((int) c) & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
-- }
-- else
-- result.WriteByte ((byte)c);
-- }
--
public static byte [] UrlEncodeToBytes (byte [] bytes, int offset, int count)
{
if (bytes == null)
return null;
--
-- int len = bytes.Length;
-- if (len == 0)
-- return new byte [0];
--
-- if (offset < 0 || offset >= len)
-- throw new ArgumentOutOfRangeException("offset");
--
-- if (count < 0 || count > len - offset)
-- throw new ArgumentOutOfRangeException("count");
--
-- MemoryStream result = new MemoryStream (count);
-- int end = offset + count;
-- for (int i = offset; i < end; i++)
-- UrlEncodeChar ((char)bytes [i], result, false);
--
-- return result.ToArray();
++#if NET_4_0
++ return HttpEncoder.Current.UrlEncode (bytes, offset, count);
++#else
++ return HttpEncoder.UrlEncodeToBytes (bytes, offset, count);
++#endif
}
public static string UrlEncodeUnicode (string str)
if (str == null)
return null;
-- if (str == "")
++ if (str.Length == 0)
return new byte [0];
MemoryStream result = new MemoryStream (str.Length);
foreach (char c in str){
-- UrlEncodeChar (c, result, true);
++ HttpEncoder.UrlEncodeChar (c, result, true);
}
return result.ToArray ();
}
/// <returns>The decoded text.</returns>
public static string HtmlDecode (string s)
{
++#if NET_4_0
if (s == null)
-- throw new ArgumentNullException ("s");
--
-- if (s.IndexOf ('&') == -1)
-- return s;
--
-- StringBuilder entity = new StringBuilder ();
-- StringBuilder output = new StringBuilder ();
-- int len = s.Length;
-- // 0 -> nothing,
-- // 1 -> right after '&'
-- // 2 -> between '&' and ';' but no '#'
-- // 3 -> '#' found after '&' and getting numbers
-- int state = 0;
-- int number = 0;
-- bool is_hex_value = false;
-- bool have_trailing_digits = false;
--
-- for (int i = 0; i < len; i++) {
-- char c = s [i];
-- if (state == 0) {
-- if (c == '&') {
-- entity.Append (c);
-- state = 1;
-- } else {
-- output.Append (c);
-- }
-- continue;
-- }
--
-- if (c == '&') {
-- state = 1;
-- if (have_trailing_digits) {
-- entity.Append (number.ToString (Helpers.InvariantCulture));
-- have_trailing_digits = false;
-- }
--
-- output.Append (entity.ToString ());
-- entity.Length = 0;
-- entity.Append ('&');
-- continue;
-- }
--
-- if (state == 1) {
-- if (c == ';') {
-- state = 0;
-- output.Append (entity.ToString ());
-- output.Append (c);
-- entity.Length = 0;
-- } else {
-- number = 0;
-- is_hex_value = false;
-- if (c != '#') {
-- state = 2;
-- } else {
-- state = 3;
-- }
-- entity.Append (c);
-- }
-- } else if (state == 2) {
-- entity.Append (c);
-- if (c == ';') {
-- string key = entity.ToString ();
-- if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2)))
-- key = Entities [key.Substring (1, key.Length - 2)].ToString ();
--
-- output.Append (key);
-- state = 0;
-- entity.Length = 0;
-- }
-- } else if (state == 3) {
-- if (c == ';') {
-- if (number > 65535) {
-- output.Append ("&#");
-- output.Append (number.ToString (Helpers.InvariantCulture));
-- output.Append (";");
-- } else {
-- output.Append ((char) number);
-- }
-- state = 0;
-- entity.Length = 0;
-- have_trailing_digits = false;
-- } else if (is_hex_value && Uri.IsHexDigit(c)) {
-- number = number * 16 + Uri.FromHex(c);
-- have_trailing_digits = true;
-- } else if (Char.IsDigit (c)) {
-- number = number * 10 + ((int) c - '0');
-- have_trailing_digits = true;
-- } else if (number == 0 && (c == 'x' || c == 'X')) {
-- is_hex_value = true;
-- } else {
-- state = 2;
-- if (have_trailing_digits) {
-- entity.Append (number.ToString (Helpers.InvariantCulture));
-- have_trailing_digits = false;
-- }
-- entity.Append (c);
-- }
-- }
-- }
--
-- if (entity.Length > 0) {
-- output.Append (entity.ToString ());
-- } else if (have_trailing_digits) {
-- output.Append (number.ToString (Helpers.InvariantCulture));
++ return null;
++
++ using (var sw = new StringWriter ()) {
++ HttpEncoder.Current.HtmlDecode (s, sw);
++ return sw.ToString ();
}
-- return output.ToString ();
++#else
++ return HttpEncoder.HtmlDecode (s);
++#endif
}
/// <summary>
/// <param name="output">The TextWriter output stream containing the decoded string. </param>
public static void HtmlDecode(string s, TextWriter output)
{
-- if (s != null)
-- output.Write (HtmlDecode (s));
-- }
--
-- /// <summary>
-- /// HTML-encodes a string and returns the encoded string.
-- /// </summary>
-- /// <param name="s">The text string to encode. </param>
-- /// <returns>The HTML-encoded text.</returns>
-- public static string HtmlEncode (string s)
-- {
-- if (s == null)
-- return null;
--
-- bool needEncode = false;
-- for (int i = 0; i < s.Length; i++) {
-- char c = s [i];
-- if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
++ if (output == null) {
#if NET_4_0
-- || c == '\''
++ throw new ArgumentNullException ("output");
++#else
++ throw new NullReferenceException (".NET emulation");
#endif
-- ) {
-- needEncode = true;
-- break;
-- }
}
--
-- if (!needEncode)
-- return s;
--
-- StringBuilder output = new StringBuilder ();
--
-- int len = s.Length;
-- for (int i = 0; i < len; i++)
-- switch (s [i]) {
-- case '&' :
-- output.Append ("&");
-- break;
-- case '>' :
-- output.Append (">");
-- break;
-- case '<' :
-- output.Append ("<");
-- break;
-- case '"' :
-- output.Append (""");
-- break;
++
++ if (!String.IsNullOrEmpty (s)) {
#if NET_4_0
-- case '\'':
-- output.Append ("'");
-- break;
++ HttpEncoder.Current.HtmlDecode (s, output);
++#else
++ output.Write (HttpEncoder.HtmlDecode (s));
#endif
-- default:
-- // MS starts encoding with &# from 160 and stops at 255.
-- // We don't do that. One reason is the 65308/65310 unicode
-- // characters that look like '<' and '>'.
--#if TARGET_JVM
-- if (s [i] > 159 && s [i] < 256) {
++ }
++ }
++
++ internal static string HtmlEncode (string s)
++ {
++#if NET_4_0
++ if (s == null)
++ return null;
++
++ using (var sw = new StringWriter ()) {
++ HttpEncoder.Current.HtmlEncode (s, sw);
++ return sw.ToString ();
++ }
#else
-- if (s [i] > 159) {
++ return HttpEncoder.HtmlEncode (s);
#endif
-- output.Append ("&#");
-- output.Append (((int) s [i]).ToString (Helpers.InvariantCulture));
-- output.Append (";");
-- } else {
-- output.Append (s [i]);
-- }
-- break;
-- }
-- return output.ToString ();
}
--
++
/// <summary>
/// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
/// </summary>
/// <param name="output">The TextWriter output stream containing the encoded string. </param>
public static void HtmlEncode(string s, TextWriter output)
{
-- if (s != null)
-- output.Write (HtmlEncode (s));
++ if (output == null) {
++#if NET_4_0
++ throw new ArgumentNullException ("output");
++#else
++ throw new NullReferenceException (".NET emulation");
++#endif
++ }
++
++ if (!String.IsNullOrEmpty (s)) {
++#if NET_4_0
++ HttpEncoder.Current.HtmlEncode (s, output);
++#else
++ output.Write (HttpEncoder.HtmlEncode (s));
++#endif
++ }
}
#if NET_4_0
public static string HtmlEncode (object value)
#endif
public static string UrlPathEncode (string s)
{
-- if (s == null || s.Length == 0)
-- return s;
--
-- MemoryStream result = new MemoryStream ();
-- int length = s.Length;
-- for (int i = 0; i < length; i++) {
-- UrlPathEncodeChar (s [i], result);
-- }
-- return Encoding.ASCII.GetString (result.ToArray ());
-- }
--
-- static void UrlPathEncodeChar (char c, Stream result)
-- {
-- if (c < 33 || c > 126) {
-- byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
-- for (int i = 0; i < bIn.Length; i++) {
-- result.WriteByte ((byte) '%');
-- int idx = ((int) bIn [i]) >> 4;
-- result.WriteByte ((byte) hexChars [idx]);
-- idx = ((int) bIn [i]) & 0x0F;
-- result.WriteByte ((byte) hexChars [idx]);
-- }
-- }
-- else if (c == ' ') {
-- result.WriteByte ((byte) '%');
-- result.WriteByte ((byte) '2');
-- result.WriteByte ((byte) '0');
-- }
-- else
-- result.WriteByte ((byte) c);
++#if NET_4_0
++ return HttpEncoder.Current.UrlPathEncode (s);
++#else
++ return HttpEncoder.UrlPathEncode (s);
++#endif
}
public static NameValueCollection ParseQueryString (string query)
System.Web.UI.WebControls/WebControlCas.cs
System.Web.UI.WebControls/XmlCas.cs
System.Web.UI.WebControls/XmlDataSourceCas.cs
++System.Web.Util/HttpEncoderTest.cs
System.Web.Util/RequestValidatorTest.cs
System.Web.Util/TransactionsCas.cs
System.Web.Util/UrlUtilsTest.cs
--- /dev/null
--- /dev/null
++//
++// Authors:
++// Marek Habersack <mhabersack@novell.com>
++//
++// Copyright (C) 2010 Novell, Inc. (http://novell.com/)
++//
++// 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.
++//
++#if NET_4_0
++using System;
++using System.Collections.Generic;
++using System.IO;
++using System.Text;
++using System.Web;
++using System.Web.Util;
++
++using NUnit.Framework;
++
++using MonoTests.SystemWeb.Framework;
++using MonoTests.stand_alone.WebHarness;
++using MonoTests.Common;
++
++namespace MonoTests.System.Web.Util
++{
++ class HttpEncoderPoker : HttpEncoder
++ {
++ public void CallHtmlAttributeEncode (string value, TextWriter output)
++ {
++ HtmlAttributeEncode (value, output);
++ }
++
++ public void CallHtmlDecode (string value, TextWriter output)
++ {
++ HtmlDecode (value, output);
++ }
++
++ public void CallHtmlEncode (string value, TextWriter output)
++ {
++ HtmlEncode (value, output);
++ }
++
++ public byte [] CallUrlEncode (byte [] bytes, int offset, int count)
++ {
++ return UrlEncode (bytes, offset, count);
++ }
++
++ public string CallUrlPathEncode (string value)
++ {
++ return UrlPathEncode (value);
++ }
++
++ public void CallHeaderNameValueEncode (string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue)
++ {
++ HeaderNameValueEncode (headerName, headerValue, out encodedHeaderName, out encodedHeaderValue);
++ }
++ }
++
++ [TestFixture]
++ public class HttpEncoderTest
++ {
++#if NET_4_0
++ const string notEncoded = "!()*-._";
++#else
++ const string notEncoded = "!'()*-._";
++#endif
++ static char [] hexChars = "0123456789abcdef".ToCharArray ();
++
++ [Test]
++ public void HtmlAttributeEncode ()
++ {
++ var encoder = new HttpEncoderPoker ();
++ var sw = new StringWriter ();
++
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ encoder.CallHtmlAttributeEncode ("string", null);
++ }, "#A1");
++
++ encoder.CallHtmlAttributeEncode ("<script>", sw);
++ Assert.AreEqual ("<script>", sw.ToString (), "#A2");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlAttributeEncode ("\"a&b\"", sw);
++ Assert.AreEqual (""a&b"", sw.ToString (), "#A3");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlAttributeEncode ("'string'", sw);
++ Assert.AreEqual ("'string'", sw.ToString (), "#A4");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlAttributeEncode ("\\string\\", sw);
++ Assert.AreEqual ("\\string\\", sw.ToString (), "#A5");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlAttributeEncode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A6");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlAttributeEncode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A7");
++ }
++
++ [Test]
++ public void HtmlDecode ()
++ {
++ var encoder = new HttpEncoderPoker ();
++ StringWriter sw;
++
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ encoder.CallHtmlDecode ("string", null);
++ }, "#A1");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlDecode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlDecode (String.Empty, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
++
++ for (int i = 0; i < decoding_pairs.Length; i += 2) {
++ sw = new StringWriter ();
++ encoder.CallHtmlDecode (decoding_pairs [i], sw);
++ Assert.AreEqual (decoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
++ }
++ }
++
++ [Test]
++ public void HtmlDecode_Specials ()
++ {
++ var encoder = new HttpEncoderPoker ();
++ var sw = new StringWriter ();
++
++ encoder.CallHtmlDecode ("♥iQj", sw);
++ Assert.AreEqual ("♥iQj", sw.ToString (), "#A1");
++ }
++
++ [Test]
++ public void HtmlEncode ()
++ {
++ var encoder = new HttpEncoderPoker ();
++ StringWriter sw;
++
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ encoder.CallHtmlEncode ("string", null);
++ }, "#A1");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlEncode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
++
++ sw = new StringWriter ();
++ encoder.CallHtmlEncode (String.Empty, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
++
++ for (int i = 0; i < encoding_pairs.Length; i += 2) {
++ sw = new StringWriter ();
++ encoder.CallHtmlEncode (encoding_pairs [i], sw);
++ Assert.AreEqual (encoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
++ }
++ }
++
++ [Test]
++ public void UrlEncode ()
++ {
++ var encoder = new HttpEncoderPoker ();
++ byte [] bytes = new byte [10];
++
++ AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
++ encoder.CallUrlEncode (bytes, -1, 1);
++ }, "#A1-1");
++
++ AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
++ encoder.CallUrlEncode (bytes, 11, 1);
++ }, "#A1-2");
++
++ AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
++ encoder.CallUrlEncode (bytes, 0, -1);
++ }, "#A1-3");
++
++ AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
++ encoder.CallUrlEncode (bytes, 01, 11);
++ }, "#A1-4");
++
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ encoder.CallUrlEncode (null, 0, 1);
++ }, "#A1-5");
++
++ for (char c = char.MinValue; c < char.MaxValue; c++) {
++ byte [] bIn;
++ bIn = Encoding.UTF8.GetBytes (c.ToString ());
++ MemoryStream expected = new MemoryStream ();
++ MemoryStream expUnicode = new MemoryStream ();
++
++ //build expected result for UrlEncode
++ for (int i = 0; i < bIn.Length; i++)
++ UrlEncodeChar ((char) bIn [i], expected, false);
++
++ byte [] expectedBytes = expected.ToArray ();
++ byte [] encodedBytes = encoder.CallUrlEncode (bIn, 0, bIn.Length);
++ Assert.IsNotNull (encodedBytes, "#B1-1");
++ Assert.AreEqual (expectedBytes.Length, encodedBytes.Length, "#B1-2");
++
++ for (int i = 0; i < expectedBytes.Length; i++)
++ Assert.AreEqual (expectedBytes [i], encodedBytes [i], String.Format ("[Char: {0}] [Pos: {1}]", c, i));
++ }
++
++ byte [] encoded = encoder.CallUrlEncode (new byte [0], 0, 0);
++ Assert.IsNotNull (encoded, "#C1-1");
++ Assert.AreEqual (0, encoded.Length, "#C1-2");
++ }
++
++ static void UrlEncodeChar (char c, Stream result, bool isUnicode)
++ {
++ if (c > 255) {
++ //FIXME: what happens when there is an internal error?
++ //if (!isUnicode)
++ // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
++ int idx;
++ int i = (int) c;
++
++ result.WriteByte ((byte) '%');
++ result.WriteByte ((byte) 'u');
++ idx = i >> 12;
++ result.WriteByte ((byte) hexChars [idx]);
++ idx = (i >> 8) & 0x0F;
++ result.WriteByte ((byte) hexChars [idx]);
++ idx = (i >> 4) & 0x0F;
++ result.WriteByte ((byte) hexChars [idx]);
++ idx = i & 0x0F;
++ result.WriteByte ((byte) hexChars [idx]);
++ return;
++ }
++
++ if (c > ' ' && notEncoded.IndexOf (c) != -1) {
++ result.WriteByte ((byte) c);
++ return;
++ }
++ if (c == ' ') {
++ result.WriteByte ((byte) '+');
++ return;
++ }
++ if ((c < '0') ||
++ (c < 'A' && c > '9') ||
++ (c > 'Z' && c < 'a') ||
++ (c > 'z')) {
++ if (isUnicode && c > 127) {
++ result.WriteByte ((byte) '%');
++ result.WriteByte ((byte) 'u');
++ result.WriteByte ((byte) '0');
++ result.WriteByte ((byte) '0');
++ } else
++ result.WriteByte ((byte) '%');
++
++ int idx = ((int) c) >> 4;
++ result.WriteByte ((byte) hexChars [idx]);
++ idx = ((int) c) & 0x0F;
++ result.WriteByte ((byte) hexChars [idx]);
++ } else
++ result.WriteByte ((byte) c);
++ }
++
++ [Test]
++ public void UrlPathEncode ()
++ {
++ var encoder = new HttpEncoderPoker ();
++
++ Assert.AreEqual (null, encoder.CallUrlPathEncode (null), "#A1-1");
++ Assert.AreEqual (String.Empty, encoder.CallUrlPathEncode (String.Empty), "#A1-2");
++
++ for (char c = char.MinValue; c < char.MaxValue; c++) {
++ MemoryStream expected = new MemoryStream ();
++ UrlPathEncodeChar (c, expected);
++
++ string exp = Encoding.ASCII.GetString (expected.ToArray ());
++ string act = encoder.CallUrlPathEncode (c.ToString ());
++ Assert.AreEqual (exp, act, "UrlPathEncode " + c.ToString ());
++ }
++ }
++
++ [Test]
++ public void UrlPathEncode2 ()
++ {
++ var encoder = new HttpEncoderPoker ();
++
++ string s = "default.xxx?sdsd=sds";
++ string s2 = encoder.CallUrlPathEncode (s);
++ Assert.AreEqual (s, s2, "UrlPathEncode " + s);
++ }
++
++ static void UrlPathEncodeChar (char c, Stream result)
++ {
++ if (c < 33 || c > 126) {
++ byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
++ for (int i = 0; i < bIn.Length; i++) {
++ result.WriteByte ((byte) '%');
++ int idx = ((int) bIn [i]) >> 4;
++ result.WriteByte ((byte) hexChars [idx]);
++ idx = ((int) bIn [i]) & 0x0F;
++ result.WriteByte ((byte) hexChars [idx]);
++ }
++ } else if (c == ' ') {
++ result.WriteByte ((byte) '%');
++ result.WriteByte ((byte) '2');
++ result.WriteByte ((byte) '0');
++ } else
++ result.WriteByte ((byte) c);
++ }
++
++ [Test]
++ public void HeaderNameValueEncode ()
++ {
++ var encoder = new HttpEncoderPoker ();
++ string encodedName;
++ string encodedValue;
++
++ encoder.CallHeaderNameValueEncode (null, null, out encodedName, out encodedValue);
++ Assert.AreEqual (null, encodedName, "#A1-1");
++ Assert.AreEqual (null, encodedValue, "#A1-2");
++
++ encoder.CallHeaderNameValueEncode (String.Empty, String.Empty, out encodedName, out encodedValue);
++ Assert.AreEqual (String.Empty, encodedName, "#A2-1");
++ Assert.AreEqual (String.Empty, encodedValue, "#A2-2");
++
++ char ch;
++ for (int i = Char.MinValue; i <= Char.MaxValue; i++) {
++ ch = (char) i;
++ encoder.CallHeaderNameValueEncode (ch.ToString (), null, out encodedName, out encodedValue);
++
++ if (headerNameEncodedChars.ContainsKey (ch))
++ Assert.AreEqual (headerNameEncodedChars [ch], encodedName, "#B1-" + i.ToString ());
++ else
++ Assert.AreEqual (ch.ToString (), encodedName, "#B1-" + i.ToString ());
++
++ encoder.CallHeaderNameValueEncode (null, ch.ToString (), out encodedName, out encodedValue);
++ if (headerValueEncodedChars.ContainsKey (ch))
++ Assert.AreEqual (headerValueEncodedChars [ch], encodedValue, "#C1-" + i.ToString ());
++ else
++ Assert.AreEqual (ch.ToString (), encodedValue, "#C1-" + i.ToString ());
++ }
++ }
++
++ Dictionary<char, string> headerNameEncodedChars = new Dictionary<char, string> {
++ {'\u0000', "%00"}, {'\u0001', "%01"}, {'\u0002', "%02"}, {'\u0003', "%03"}, {'\u0004', "%04"},
++ {'\u0005', "%05"}, {'\u0006', "%06"}, {'\u0007', "%07"}, {'\u0008', "%08"}, {'\u000A', "%0a"},
++ {'\u000B', "%0b"}, {'\u000C', "%0c"}, {'\u000D', "%0d"}, {'\u000E', "%0e"}, {'\u000F', "%0f"},
++ {'\u0010', "%10"}, {'\u0011', "%11"}, {'\u0012', "%12"}, {'\u0013', "%13"}, {'\u0014', "%14"},
++ {'\u0015', "%15"}, {'\u0016', "%16"}, {'\u0017', "%17"}, {'\u0018', "%18"}, {'\u0019', "%19"},
++ {'\u001A', "%1a"}, {'\u001B', "%1b"}, {'\u001C', "%1c"}, {'\u001D', "%1d"}, {'\u001E', "%1e"},
++ {'\u001F', "%1f"}, {'\7f', "%7f"},
++ };
++
++ Dictionary<char, string> headerValueEncodedChars = new Dictionary<char, string> {
++ {'\u0000', "%00"}, {'\u0001', "%01"}, {'\u0002', "%02"}, {'\u0003', "%03"}, {'\u0004', "%04"},
++ {'\u0005', "%05"}, {'\u0006', "%06"}, {'\u0007', "%07"}, {'\u0008', "%08"}, {'\u000A', "%0a"},
++ {'\u000B', "%0b"}, {'\u000C', "%0c"}, {'\u000D', "%0d"}, {'\u000E', "%0e"}, {'\u000F', "%0f"},
++ {'\u0010', "%10"}, {'\u0011', "%11"}, {'\u0012', "%12"}, {'\u0013', "%13"}, {'\u0014', "%14"},
++ {'\u0015', "%15"}, {'\u0016', "%16"}, {'\u0017', "%17"}, {'\u0018', "%18"}, {'\u0019', "%19"},
++ {'\u001A', "%1a"}, {'\u001B', "%1b"}, {'\u001C', "%1c"}, {'\u001D', "%1d"}, {'\u001E', "%1e"},
++ {'\u001F', "%1f"}, {'\7f', "%7f"},
++ };
++
++ #region Long arrays of strings
++ string [] decoding_pairs = {
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅  εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ⟨«←⇐⌈“≤⌊∗◊‎‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ"√⟩»→⇒⌉”ℜ®⌋ρΡ‏›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ‍‌",
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅ εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ›’‚šŠ⋅§σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ",
++ @"á?dCO+6Mk'2RÁT148quH^^=972 â#Âjs""{1LZz)U´u@Rv-05n Læ3x}Æ!à,=*-J*À=P|BℵY<g?cg>jB)αΑ9#4V`)|&J/n&JVK56X\2q*F∧Js∠6k6å""Å?rGt≈\F <9IM{s-ã(ShKÃw/[%,ksf93'kä+b$@Q{5ÄUo„aN~'ycb>VKGcjoβoR8""%B`LΒI7g""k5]A>^B¦lllUPg5#b•8Pw,bwSiY ""5]a∩_R@m&D+Lz""dKLTçKH&I}6)_QÇmS%BZV/*Xo¸s5[¢-$|)|L&5~χY/3cdUrnΧ8ˆ&)@KU@scEW2I♣p2,US7f>&m!F≅Fr9A%,Ci'y[]F+©PY↵FeCrQI<:pPP~;>∪¤y J#R&%%i†Ow,‡T↓KpY`WSAo$i:r⇓']=°k12&UI@_δ(9xDΔdz♦RJdB""F^Y}g÷2kbZ2>@yBfué9!9J(vÉ\TwTS2X5iêSLWaTMQE]e&ÊjW{\#JAh{Ua=è5È6/GY∅U n: dcSfεΕ1Yoi?X≡.-s!n|i9U?3:6η+|6Ηha?>fm!v,ðc;Ky]88Ð4T@qO#.ë@Kl3%ËX-VvUoE& €o9T:r8\||^ha;∃1;/BMT*xJ(a>BƒbH'-TH!6NrP∀n½5Fqvq_e9_""XJ¼vmLXTtu:TVZ,¾syl;qEe:b$5j⁄b Hg%Tγ[ΓH≥>{1wT↔o6i~jjKC02⇔Q4i6m(2tpl♥iQj!…4le""4} Lv5{CsíD*u]jÍs}#br=îfhΡ_B:|ìk2U7lZ;_sI\c]Ìsℑ T!5h"".um9ctz∞ YDL∫b(S^ιbCmΙ_L(\-F¿m9g.h$^HSv∈cWH#>ïm0ÏKtgRE3c5@0&κT[2?\>T^H**Κ=^6 [λumΛ[3wQ5gT?H(Bo\/⟨6car8P@AjF4e|b«397jxG:m←U~?~""f⇐`O9iwJ#⌈L:q-* !V“os)Wq6S{t≤=80A⌊#tS6∗x`g6a>]U-b◊SHb/-]‎m9dm""/d<;xR)4‹jrb/,q‘RW}n2shoM11D|<{}*]WPE#d#¯—yhT kµ·`f~o−{Kmfμd7fmtΜPT@OOrzj∇y ;M01XyI: +l<–x5|a>62y≠GNKJQjmj3∋Az¬?V∉,<⊄R]LcñkV:Ñ9LLf&Z%`d-H^Lνv_yXhtΝR1yuF!ój3]zOwQf_YtT9tÓ}s]&1TôÔ2lENœ:Rp^X+tPNL.Œx0 ?c3ZPò3Ò‾@nEωuK-*HjL-h5zΩ~xοFNQ8D#{ΟYj|]'LX⊕ie-Y∨ª$*.cºVM7KQ.b]hmV øx{R>J-D_0vØHpõL'IGÕ`⊗E ö>KNCmÖO2dH_&jd^ >2¶U%""_n∂U>F‰?TSz0~~⊥!p@G~bH^Eφdg)AΦ J<<j_,7Q)dEs,πZΠ_B<@%.&?70ϖ9Y^C|VRPrb4}±Yn=9=SQ;`}(e%£y;6|RN;|w′AH=XXf″∏DGf6ol∝ψ]UXZU\vzW4Ψe`NY[vrvs"xay√[@\scKIznodD<s⟩PB C)<itm+»{t-L→s^^x<:&sh3⇒p^s6Y~3Csw=⌉_pKnhDNTmA*p”]yG6;,ZuPxℜxsd®`hXlUn~(pK=N:^⌋OS""P{%j-Wjbx.wρts^Ρr$h<:u^‏Vj}\?7SIauBh›u[ !rto/[UHog’xe6gY<24BY.‚`ZNR}šuY{Gg;FŠ⋅az4TlWKYbJ.h§c`9FrP­5_)σwx.nP}z@ΣNP9-$@j5ς∼'ogIt:.@Gul♠""p\\rH[)⊂Om/|3G+BQe⊆5s!f/O9SA\RJkv∑GOFMAXu⊃W¹²L`r""}u/n³.ouLC⊇(fß{τB%e [Τ$DD>kIdV#X`?^\∴|S?Wθx)2P.![^5ΘzqF""pjϑ#BE1u? GGG>(EQEþ!""y1r/Þm&@[\mw[kNR˜|1G#i[(×X<UotTID uY™sWW+TbxYúkQXr!H6Ú~0TiH1POP↑(CRZttz\EY<⇑&bN7ki|ûr,3j!e$kJE&Z$zÛ5{0[bvD""[<P)ù;1EeRSrz/gY/Ù/1 S`I*q8:Z-¨%N)WϒO[2P9 ?υOΥtüÜVLq℘2""(Z'~~""uiXξNCqΞ9)S]^v 3ýx""|2&$`GÝ<&Nr¥[3NB5fÿ c""MzMw3(;""sŸζ{!Ζoevp1'j(E`vJ‍Si‌gw>yc*U",
++ @"á?dCO+6Mk'2RÁT148quH^^=972 â#Âjs""{1LZz)U´u@Rv-05n Læ3x}Æ!à,=*-J*À=P|BℵY<g?cg>jB)αΑ9#4V`)|&J/n&JVK56X\2q*F∧Js∠6k6å""Å?rGt≈\F <9IM{s-ã(ShKÃw/[%,ksf93'kä+b$@Q{5ÄUo„aN~'ycb>VKGcjoβoR8""%B`LΒI7g""k5]A>^B¦lllUPg5#b•8Pw,bwSiY ""5]a∩_R@m&D+Lz""dKLTçKH&I}6)_QÇmS%BZV/*Xo¸s5[¢-$|)|L&5~χY/3cdUrnΧ8ˆ&)@KU@scEW2I♣p2,US7f>&m!F≅Fr9A%,Ci'y[]F+©PY↵FeCrQI<:pPP~;>∪¤y J#R&%%i†Ow,‡T↓KpY`WSAo$i:r⇓']=°k12&UI@_δ(9xDΔdz♦RJdB""F^Y}g÷2kbZ2>@yBfué9!9J(vÉ\TwTS2X5iêSLWaTMQE]e&ÊjW{\#JAh{Ua=è5È6/GY∅U n: dcSfεΕ1Yoi?X≡.-s!n|i9U?3:6η+|6Ηha?>fm!v,ðc;Ky]88Ð4T@qO#.ë@Kl3%ËX-VvUoE& €o9T:r8\||^ha;∃1;/BMT*xJ(a>BƒbH'-TH!6NrP∀n½5Fqvq_e9_""XJ¼vmLXTtu:TVZ,¾syl;qEe:b$5j⁄b Hg%Tγ[ΓH≥>{1wT↔o6i~jjKC02⇔Q4i6m(2tpl♥iQj!…4le""4} Lv5{CsíD*u]jÍs}#br=îfhΡ_B:|ìk2U7lZ;_sI\c]Ìsℑ T!5h"".um9ctz∞ YDL∫b(S^ιbCmΙ_L(\-F¿m9g.h$^HSv∈cWH#>ïm0ÏKtgRE3c5@0&κT[2?\>T^H**Κ=^6 [λumΛ[3wQ5gT?H(Bo\/〈6car8P@AjF4e|b«397jxG:m←U~?~""f⇐`O9iwJ#⌈L:q-* !V“os)Wq6S{t≤=80A⌊#tS6∗x`g6a>]U-b◊SHb/-]m9dm""/d<;xR)4‹jrb/,q‘RW}n2shoM11D|<{}*]WPE#d#¯—yhT kµ·`f~o−{Kmfμd7fmtΜPT@OOrzj∇y ;M01XyI: +l<–x5|a>62y≠GNKJQjmj3∋Az¬?V∉,<⊄R]LcñkV:Ñ9LLf&Z%`d-H^Lνv_yXhtΝR1yuF!ój3]zOwQf_YtT9tÓ}s]&1TôÔ2lENœ:Rp^X+tPNL.Œx0 ?c3ZPò3Ò‾@nEωuK-*HjL-h5zΩ~xοFNQ8D#{ΟYj|]'LX⊕ie-Y∨ª$*.cºVM7KQ.b]hmV øx{R>J-D_0vØHpõL'IGÕ`⊗E ö>KNCmÖO2dH_&jd^ >2¶U%""_n∂U>F‰?TSz0~~⊥!p@G~bH^Eφdg)AΦ J<<j_,7Q)dEs,πZΠ_B<@%.&?70ϖ9Y^C|VRPrb4}±Yn=9=SQ;`}(e%£y;6|RN;|w′AH=XXf″∏DGf6ol∝ψ]UXZU\vzW4Ψe`NY[vrvs""xay√[@\scKIznodD<s〉PB C)<itm+»{t-L→s^^x<:&sh3⇒p^s6Y~3Csw=⌉_pKnhDNTmA*p”]yG6;,ZuPxℜxsd®`hXlUn~(pK=N:^⌋OS""P{%j-Wjbx.wρts^Ρr$h<:u^Vj}\?7SIauBh›u[ !rto/[UHog’xe6gY<24BY.‚`ZNR}šuY{Gg;FŠ⋅az4TlWKYbJ.h§c`9FrP5_)σwx.nP}z@ΣNP9-$@j5ς∼'ogIt:.@Gul♠""p\\rH[)⊂Om/|3G+BQe⊆5s!f/O9SA\RJkv∑GOFMAXu⊃W¹²L`r""}u/n³.ouLC⊇(fß{τB%e [Τ$DD>kIdV#X`?^\∴|S?Wθx)2P.![^5ΘzqF""pjϑ#BE1u? GGG>(EQEþ!""y1r/Þm&@[\mw[kNR˜|1G#i[(×X<UotTID uY™sWW+TbxYúkQXr!H6Ú~0TiH1POP↑(CRZttz\EY<⇑&bN7ki|ûr,3j!e$kJE&Z$zÛ5{0[bvD""[<P)ù;1EeRSrz/gY/Ù/1 S`I*q8:Z-¨%N)WϒO[2P9 ?υOΥtüÜVLq℘2""(Z'~~""uiXξNCqΞ9)S]^v 3ýx""|2&$`GÝ<&Nr¥[3NB5fÿ c""MzMw3(;""sŸζ{!Ζoevp1'j(E`vJSigw>yc*U",
++ @"áÁâ´æÆàÀ&alefsym&alpha&Alpha&&and&angåÅ&asympãÃäÄ&bdquo&beta&Beta¦&bull&capçǸ¢&chi&Chi&circ&clubs&cong©&crarr&cup¤&dagger&Dagger&darr&dArr°&delta&Delta&diams÷éÉêÊèÈ&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&EtaðÐëË&euro&exist&fnof&forall½¼¾&frasl&gamma&Gamma&ge>&harr&hArr&hearts&hellipíÍîΡìÌ&image&infin&int&iota&Iota¿&isinïÏ&kappa&Kappa&lambda&Lambda&lang«&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo<¯&mdashµ·&minus&mu&Mu&nabla &ndash&ne&ni¬¬in&nsubñÑ&nu&NuóÓôÔ&oelig&OEligòÒ&oline&omega&Omega&omicron&Omicron&oplus&orªºøØõÕ&otimesöÖ¶&part&permil&perp&phi&Phi&pi&Pi&piv±£&prime&Prime&prod&prop&psi&Psi"&radic&rang»&rarr&rArr&rceil&rdquo&real®&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot§­&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup¹²³&supeß&tau&Tau&there4&theta&Theta&thetasym&thinspþÞ&tilde×&tradeúÚ&uarr&uArrûÛùÙ¨&upsih&upsilon&UpsilonüÜ&weierp&xi&XiýÝ¥ÿ&Yuml&zeta&Zeta&zwj&zwnj",
++ @"áÁâ´æÆàÀ&alefsym&alpha&Alpha&&and&angåÅ&asympãÃäÄ&bdquo&beta&Beta¦&bull&capçǸ¢&chi&Chi&circ&clubs&cong©&crarr&cup¤&dagger&Dagger&darr&dArr°&delta&Delta&diams÷éÉêÊèÈ&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&EtaðÐëË&euro&exist&fnof&forall½¼¾&frasl&gamma&Gamma&ge>&harr&hArr&hearts&hellipíÍîΡìÌ&image&infin&int&iota&Iota¿&isinïÏ&kappa&Kappa&lambda&Lambda&lang«&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo<¯&mdashµ·&minus&mu&Mu&nabla &ndash&ne&ni¬¬in&nsubñÑ&nu&NuóÓôÔ&oelig&OEligòÒ&oline&omega&Omega&omicron&Omicron&oplus&orªºøØõÕ&otimesöÖ¶&part&permil&perp&phi&Phi&pi&Pi&piv±£&prime&Prime&prod&prop&psi&Psi"&radic&rang»&rarr&rArr&rceil&rdquo&real®&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot§­&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup¹²³&supeß&tau&Tau&there4&theta&Theta&thetasym&thinspþÞ&tilde×&tradeúÚ&uarr&uArrûÛùÙ¨&upsih&upsilon&UpsilonüÜ&weierp&xi&XiýÝ¥ÿ&Yuml&zeta&Zeta&zwj&zwnj",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @"�	

 ",
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ @"�	

 ",
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ " ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++};
++ string [] encoding_pairs = {
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅ εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ›’‚šŠ⋅§σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ",
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅ εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ"√〉»→⇒⌉”ℜ®⌋ρΡ›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ",
++ @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N""åzcWM'z""gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x""ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ""+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT""qAκ*/ΚλN>j}""WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[""3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\""µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S"",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI""Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu""ο:Mz$(""joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|""yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£""'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO""'4""/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6oTxP""""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+59.W\v]GGtKvCC0`A",
++ @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N"åzcWM'z"gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x"ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ"+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT"qAκ*/ΚλN>j}"WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8["3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\"µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI"Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu"ο:Mz$("joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|"yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£"'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO"'4"/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6oTxP""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'­qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+59.W\v]GGtKvCC0`A",
++ @"áÁâ´æÆàÀ&alefsym&alpha&Alpha&&and&angåÅ&asympãÃäÄ&bdquo&beta&Beta¦&bull&capçǸ¢&chi&Chi&circ&clubs&cong©&crarr&cup¤&dagger&Dagger&darr&dArr°&delta&Delta&diams÷éÉêÊèÈ&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&EtaðÐëË&euro&exist&fnof&forall½¼¾&frasl&gamma&Gamma&ge>&harr&hArr&hearts&hellipíÍîΡìÌ&image&infin&int&iota&Iota¿&isinïÏ&kappa&Kappa&lambda&Lambda&lang«&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo<¯&mdashµ·&minus&mu&Mu&nabla &ndash&ne&ni¬¬in&nsubñÑ&nu&NuóÓôÔ&oelig&OEligòÒ&oline&omega&Omega&omicron&Omicron&oplus&orªºøØõÕ&otimesöÖ¶&part&permil&perp&phi&Phi&pi&Pi&piv±£&prime&Prime&prod&prop&psi&Psi"&radic&rang»&rarr&rArr&rceil&rdquo&real®&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot§­&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup¹²³&supeß&tau&Tau&there4&theta&Theta&thetasym&thinspþÞ&tilde×&tradeúÚ&uarr&uArrûÛùÙ¨&upsih&upsilon&UpsilonüÜ&weierp&xi&XiýÝ¥ÿ&Yuml&zeta&Zeta&zwj&zwnj",
++ @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
++ @" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ "&#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ "&#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ @" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++};
++ #endregion
++ }
++}
++#endif
using System.Collections.Specialized;
using NUnit.Framework;
++using MonoTests.Common;
namespace MonoTests.System.Web {
[TestFixture]
-- public class HttpUtilityTest {
++ public class HttpUtilityTest
++ {
[Test]
public void HtmlAttributeEncode ()
{
-- Assert.AreEqual ("<script>", HttpUtility.HtmlAttributeEncode ("<script>"));
-- Assert.AreEqual (""a&b"", HttpUtility.HtmlAttributeEncode ("\"a&b\""));
++ Assert.AreEqual (null, HttpUtility.HtmlAttributeEncode (null), "#A1");
++ Assert.AreEqual (String.Empty, HttpUtility.HtmlAttributeEncode (String.Empty), "#A2");
++ Assert.AreEqual ("<script>", HttpUtility.HtmlAttributeEncode ("<script>"), "#A3");
++ Assert.AreEqual (""a&b"", HttpUtility.HtmlAttributeEncode ("\"a&b\""), "#A4");
#if NET_4_0
-- Assert.AreEqual ("'string'", HttpUtility.HtmlAttributeEncode ("'string'"));
++ Assert.AreEqual ("'string'", HttpUtility.HtmlAttributeEncode ("'string'"), "#A5");
#else
-- Assert.AreEqual ("'string'", HttpUtility.HtmlAttributeEncode ("'string'"));
++ Assert.AreEqual ("'string'", HttpUtility.HtmlAttributeEncode ("'string'"), "#A5");
#endif
}
++ [Test]
++ public void HtmlAttributeEncode_String_TextWriter ()
++ {
++ var sw = new StringWriter ();
++#if NET_4_0
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ HttpUtility.HtmlAttributeEncode ("string", null);
++ }, "#A1");
++#else
++ AssertExtensions.Throws<NullReferenceException> (() => {
++ HttpUtility.HtmlAttributeEncode ("string", null);
++ }, "#A1");
++#endif
++
++ HttpUtility.HtmlAttributeEncode ("<script>", sw);
++ Assert.AreEqual ("<script>", sw.ToString (), "#A2");
++
++ sw = new StringWriter ();
++ HttpUtility.HtmlAttributeEncode ("\"a&b\"", sw);
++ Assert.AreEqual (""a&b"", sw.ToString (), "#A3");
++
++ sw = new StringWriter ();
++ HttpUtility.HtmlAttributeEncode ("'string'", sw);
++#if NET_4_0
++ Assert.AreEqual ("'string'", sw.ToString (), "#A4");
++#else
++ Assert.AreEqual ("'string'", sw.ToString (), "#A4");
++#endif
++ sw = new StringWriter ();
++ HttpUtility.HtmlAttributeEncode ("\\string\\", sw);
++ Assert.AreEqual ("\\string\\", sw.ToString (), "#A5");
++
++ sw = new StringWriter ();
++ HttpUtility.HtmlAttributeEncode (String.Empty, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A6");
++
++ sw = new StringWriter ();
++ HttpUtility.HtmlAttributeEncode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A7");
++ }
++
++ [Test]
++ public void HtmlDecode ()
++ {
++ Assert.AreEqual (null, HttpUtility.HtmlDecode (null), "#A1");
++ Assert.AreEqual (String.Empty, HttpUtility.HtmlDecode (String.Empty), "#A2");
++
++ for (int i = 0; i < decoding_pairs.Length; i += 2)
++ Assert.AreEqual (decoding_pairs [i + 1], HttpUtility.HtmlDecode (decoding_pairs [i]), "#B" + (i / 2).ToString ());
++ }
++
++ [Test]
++ public void HtmlDecode_String_TextWriter ()
++ {
++ StringWriter sw;
++#if NET_4_0
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ HttpUtility.HtmlDecode ("string", null);
++ }, "#A1");
++#else
++ AssertExtensions.Throws<NullReferenceException> (() => {
++ HttpUtility.HtmlDecode ("string", null);
++ }, "#A1");
++#endif
++
++ sw = new StringWriter ();
++ HttpUtility.HtmlDecode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
++
++ sw = new StringWriter ();
++ HttpUtility.HtmlDecode (String.Empty, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
++
++ for (int i = 0; i < decoding_pairs.Length; i += 2) {
++ sw = new StringWriter ();
++ HttpUtility.HtmlDecode (decoding_pairs [i], sw);
++ Assert.AreEqual (decoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
++ }
++ }
++
[Test]
public void HtmlEncode_LtGt ()
{
public void HtmlEncode_XSS ()
{
string problem = "\xff1cscript\xff1e"; // unicode looks alike <script>
-- byte[] utf8data = Encoding.UTF8.GetBytes (problem);
++ byte [] utf8data = Encoding.UTF8.GetBytes (problem);
Encoding win1251 = Encoding.GetEncoding ("windows-1251");
-- byte[] windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
++ byte [] windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
// now it's a real problem
Assert.AreEqual ("<script>", Encoding.ASCII.GetString (windata), "<script>");
string encoded = HttpUtility.HtmlEncode (problem);
Assert.AreEqual ("<script>", encoded, "<script>");
--
++
utf8data = Encoding.UTF8.GetBytes (encoded);
windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
Assert.AreEqual ("<script>", Encoding.ASCII.GetString (windata), "ok");
for (int i = 0; i < len; i++) {
c = s [i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
-- sb.AppendFormat ("\\u{0:x4}", (int)c);
-- else switch ((int)c) {
-- case 8:
-- sb.Append ("\\b");
-- break;
--
-- case 9:
-- sb.Append ("\\t");
-- break;
--
-- case 10:
-- sb.Append ("\\n");
-- break;
++ sb.AppendFormat ("\\u{0:x4}", (int) c);
++ else switch ((int) c) {
++ case 8:
++ sb.Append ("\\b");
++ break;
++
++ case 9:
++ sb.Append ("\\t");
++ break;
++
++ case 10:
++ sb.Append ("\\n");
++ break;
++
++ case 12:
++ sb.Append ("\\f");
++ break;
++
++ case 13:
++ sb.Append ("\\r");
++ break;
++
++ case 34:
++ sb.Append ("\\\"");
++ break;
++
++ case 92:
++ sb.Append ("\\\\");
++ break;
++
++ default:
++ sb.Append (c);
++ break;
++ }
++ }
-- case 12:
-- sb.Append ("\\f");
-- break;
++ if (addDoubleQuotes)
++ sb.Append ('"');
-- case 13:
-- sb.Append ("\\r");
-- break;
++ return sb.ToString ();
++ }
++#endif
++ [Test]
++ public void HtmlEncode_2 ()
++ {
++ StringWriter sw;
++#if NET_4_0
++ AssertExtensions.Throws<ArgumentNullException> (() => {
++ HttpUtility.HtmlEncode ("string", null);
++ }, "#A1");
++#else
++ AssertExtensions.Throws<NullReferenceException> (() => {
++ HttpUtility.HtmlEncode ("string", null);
++ }, "#A1");
++#endif
-- case 34:
-- sb.Append ("\\\"");
-- break;
++ sw = new StringWriter ();
++ HttpUtility.HtmlEncode (null, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
-- case 92:
-- sb.Append ("\\\\");
-- break;
++ sw = new StringWriter ();
++ HttpUtility.HtmlEncode (String.Empty, sw);
++ Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
-- default:
-- sb.Append (c);
-- break;
-- }
++ for (int i = 0; i < encoding_pairs.Length; i += 2) {
++ sw = new StringWriter ();
++ HttpUtility.HtmlEncode (encoding_pairs [i], sw);
++ Assert.AreEqual (encoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
}
++ }
-- if (addDoubleQuotes)
-- sb.Append ('"');
++ [Test]
++ public void HtmlEncode_3 ()
++ {
++ Assert.AreEqual (null, HttpUtility.HtmlEncode (null), "#A1");
++ Assert.AreEqual (String.Empty, HttpUtility.HtmlEncode (String.Empty), "#A2");
-- return sb.ToString ();
++ for (int i = 0; i < encoding_pairs.Length; i += 2)
++ Assert.AreEqual (encoding_pairs [i + 1], HttpUtility.HtmlEncode (encoding_pairs [i]), "#B" + (i / 2).ToString ());
}
--#endif
++
[Test]
#if !TARGET_JVM
[Category ("NotWorking")]
#endif
-- public void HtmlEncode () {
++ public void HtmlEncode ()
++ {
for (char c = char.MinValue; c < char.MaxValue; c++) {
String exp = HtmlEncode (c.ToString ());
String act = HttpUtility.HtmlEncode (c.ToString ());
Assert.AreEqual (exp, act, "HtmlEncode " + c.ToString () + " [" + (int) c + "]");
}
}
--
-- string HtmlEncode (string s) {
++
++ string HtmlEncode (string s)
++ {
if (s == null)
return null;
char c = s [i];
if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
#if NET_4_0
-- || c == '\''
++ || c == '\''
#endif
-- ) {
++) {
needEncode = true;
break;
}
int len = s.Length;
for (int i = 0; i < len; i++)
switch (s [i]) {
-- case '&':
-- output.Append ("&");
-- break;
-- case '>':
-- output.Append (">");
-- break;
-- case '<':
-- output.Append ("<");
-- break;
-- case '"':
-- output.Append (""");
-- break;
++ case '&':
++ output.Append ("&");
++ break;
++ case '>':
++ output.Append (">");
++ break;
++ case '<':
++ output.Append ("<");
++ break;
++ case '"':
++ output.Append (""");
++ break;
#if NET_4_0
-- case '\'':
-- output.Append ("'");
-- break;
++ case '\'':
++ output.Append ("'");
++ break;
#endif
-- default:
-- // MS starts encoding with &# from 160 and stops at 255.
-- // We don't do that. One reason is the 65308/65310 unicode
-- // characters that look like '<' and '>'.
-- if (s [i] > 159 && s [i] < 256) {
-- output.Append ("&#");
-- output.Append (((int) s [i]).ToString ());
-- output.Append (";");
-- }
-- else {
-- output.Append (s [i]);
-- }
-- break;
++ default:
++ // MS starts encoding with &# from 160 and stops at 255.
++ // We don't do that. One reason is the 65308/65310 unicode
++ // characters that look like '<' and '>'.
++ if (s [i] > 159 && s [i] < 256) {
++ output.Append ("&#");
++ output.Append (((int) s [i]).ToString ());
++ output.Append (";");
++ } else {
++ output.Append (s [i]);
++ }
++ break;
}
return output.ToString ();
}
[Test]
public void UrlDecodeToBytes ()
{
-- byte[] bytes = HttpUtility.UrlDecodeToBytes ("%5c");
++ byte [] bytes = HttpUtility.UrlDecodeToBytes ("%5c");
Assert.AreEqual (1, bytes.Length, "#1");
Assert.AreEqual (0x5c, bytes [0], "#2");
bytes = HttpUtility.UrlDecodeToBytes ("%5");
[Test]
public void UrlDecode1 ()
{
-- Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
++ Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
"UrlDecode1 #1");
--
-- Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
++
++ Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
"UrlDecode1 #2");
--
-- Assert.AreEqual ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
++
++ Assert.AreEqual ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
"UrlDecode1 #3");
-- Assert.AreEqual ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
++ Assert.AreEqual ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
"UrlDecode1 #4");
-- Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
++ Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
"UrlDecode1 #5");
-- Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
++ Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
"UrlDecode1 #6");
--
-- Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
++
++ Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
"UrlDecode1 #7");
--
-- Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
-- HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
++
++ Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
++ HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
"UrlDecode1 #8");
}
public void UrlDecode2 ()
{
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
++ Encoding.UTF8),
"UrlDecode2 #1");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
++ Encoding.UTF8),
"UrlDecode2 #2");
Assert.AreEqual (
-- "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
++ "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
++ Encoding.UTF8),
"UrlDecode2 #3");
Assert.AreEqual (
-- "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
++ "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
++ Encoding.UTF8),
"UrlDecode2 #4");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
++ Encoding.UTF8),
"UrlDecode2 #5");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
++ Encoding.UTF8),
"UrlDecode2 #6");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
++ Encoding.UTF8),
"UrlDecode2 #7");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
HttpUtility.UrlDecode (
-- Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
-- Encoding.UTF8),
++ Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
++ Encoding.UTF8),
"UrlDecode2 #8");
}
public void UrlDecodeToBytes2 ()
{
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r")),
"UrlDecodeToBytes2 #1");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r")),
"UrlDecodeToBytes2 #2");
Assert.AreEqual (
-- "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
++ "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r")),
"UrlDecodeToBytes2 #3");
Assert.AreEqual (
-- "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
++ "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r")),
"UrlDecodeToBytes2 #4");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r")),
"UrlDecodeToBytes2 #5");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r")),
"UrlDecodeToBytes2 #6");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r")),
"UrlDecodeToBytes2 #7");
Assert.AreEqual (
-- "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
++ "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
Encoding.UTF8.GetString (
-- HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r")),
++ HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r")),
"UrlDecodeToBytes2 #8");
}
--
++
[Test]
public void EscapedCharacters ()
{
for (int i = 0; i < 256; i++) {
string str = new string ((char) i, 1);
string encoded = HttpUtility.HtmlEncode (str);
-- if ((i > 159 && i < 256 ) || i == '&' || i == '<' || i == '>' || i == '"'
++ if ((i > 159 && i < 256) || i == '&' || i == '<' || i == '>' || i == '"'
#if NET_4_0
-- || i == '\''
++ || i == '\''
#endif
-- ) {
++) {
if (encoded [0] != '&' || encoded [encoded.Length - 1] != ';')
Assert.Fail ("Failed for i = " + i);
} else if (encoded.Length != 1) {
}
}
-- [Test (Description="Bug #507666")]
++ [Test (Description = "Bug #507666")]
public void UrlDecode_Bug507666 ()
{
// Get Encoding object.
var enc_utf8 = Encoding.UTF8;
-- var enc_sjis = Encoding.GetEncoding(932);
++ var enc_sjis = Encoding.GetEncoding (932);
// Generate equiv. client request query string with url-encoded shift_jis string.
var utf8_string = "紅茶"; // it's UTF-8 string
-- var utf8_bin = enc_utf8.GetBytes(utf8_string); // convert to UTF-8 byte[]
-- var sjis_bin = Encoding.Convert(enc_utf8, enc_sjis, utf8_bin); // convert to Shift_jis byte[]
-- var urlenc_string = HttpUtility.UrlEncode(sjis_bin); // equiv. client request query string.
++ var utf8_bin = enc_utf8.GetBytes (utf8_string); // convert to UTF-8 byte[]
++ var sjis_bin = Encoding.Convert (enc_utf8, enc_sjis, utf8_bin); // convert to Shift_jis byte[]
++ var urlenc_string = HttpUtility.UrlEncode (sjis_bin); // equiv. client request query string.
// Test using UrlDecode only.
-- var decoded_by_web = HttpUtility.UrlDecode(urlenc_string, enc_sjis);
++ var decoded_by_web = HttpUtility.UrlDecode (urlenc_string, enc_sjis);
Assert.AreEqual (utf8_string, decoded_by_web, "#A1");
}
--
++
[Test]
public void Decode1 ()
{
Assert.AreEqual ("\xE9", HttpUtility.HtmlDecode ("é"));
}
-- [Test (Description="Bug #585992")]
++ [Test (Description = "Bug #585992")]
public void Decode2 ()
{
string encodedSource = "© == © == © and Γ == Γ == Γ";
Assert.AreEqual (utf8Result, HttpUtility.HtmlDecode (encodedSource), "#A1");
}
--
++
[Test]
public void RoundTrip ()
{
string x = "<html>& hello+= world!";
-- string y = HttpUtility.HtmlEncode (x);
-- string z = HttpUtility.HtmlDecode (y);
++ string y = HttpUtility.HtmlEncode (x);
++ string z = HttpUtility.HtmlDecode (y);
Assert.AreEqual (x, z);
}
const string notEncoded = "!'()*-._";
#endif
-- static void UrlPathEncodeChar (char c, Stream result) {
++ static void UrlPathEncodeChar (char c, Stream result)
++ {
#if NET_2_0
if (c < 33 || c > 126) {
#else
idx = ((int) bIn [i]) & 0x0F;
result.WriteByte ((byte) hexChars [idx]);
}
-- }
-- else if (c == ' ') {
++ } else if (c == ' ') {
result.WriteByte ((byte) '%');
result.WriteByte ((byte) '2');
result.WriteByte ((byte) '0');
-- }
-- else
++ } else
result.WriteByte ((byte) c);
}
-- static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
++ static void UrlEncodeChar (char c, Stream result, bool isUnicode)
++ {
if (c > 255) {
//FIXME: what happens when there is an internal error?
//if (!isUnicode)
int idx;
int i = (int) c;
-- result.WriteByte ((byte)'%');
-- result.WriteByte ((byte)'u');
++ result.WriteByte ((byte) '%');
++ result.WriteByte ((byte) 'u');
idx = i >> 12;
-- result.WriteByte ((byte)hexChars [idx]);
++ result.WriteByte ((byte) hexChars [idx]);
idx = (i >> 8) & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
++ result.WriteByte ((byte) hexChars [idx]);
idx = (i >> 4) & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
++ result.WriteByte ((byte) hexChars [idx]);
idx = i & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
++ result.WriteByte ((byte) hexChars [idx]);
return;
}
--
-- if (c>' ' && notEncoded.IndexOf (c)!=-1) {
-- result.WriteByte ((byte)c);
++
++ if (c > ' ' && notEncoded.IndexOf (c) != -1) {
++ result.WriteByte ((byte) c);
return;
}
-- if (c==' ') {
-- result.WriteByte ((byte)'+');
++ if (c == ' ') {
++ result.WriteByte ((byte) '+');
return;
}
-- if ( (c < '0') ||
++ if ((c < '0') ||
(c < 'A' && c > '9') ||
(c > 'Z' && c < 'a') ||
(c > 'z')) {
if (isUnicode && c > 127) {
-- result.WriteByte ((byte)'%');
-- result.WriteByte ((byte)'u');
-- result.WriteByte ((byte)'0');
-- result.WriteByte ((byte)'0');
-- }
-- else
-- result.WriteByte ((byte)'%');
--
++ result.WriteByte ((byte) '%');
++ result.WriteByte ((byte) 'u');
++ result.WriteByte ((byte) '0');
++ result.WriteByte ((byte) '0');
++ } else
++ result.WriteByte ((byte) '%');
++
int idx = ((int) c) >> 4;
-- result.WriteByte ((byte)hexChars [idx]);
++ result.WriteByte ((byte) hexChars [idx]);
idx = ((int) c) & 0x0F;
-- result.WriteByte ((byte)hexChars [idx]);
-- }
-- else
-- result.WriteByte ((byte)c);
++ result.WriteByte ((byte) hexChars [idx]);
++ } else
++ result.WriteByte ((byte) c);
}
[Test]
public void UrlEncode ()
{
-- for (char c=char.MinValue; c<char.MaxValue; c++) {
++ for (char c = char.MinValue; c < char.MaxValue; c++) {
byte [] bIn;
bIn = Encoding.UTF8.GetBytes (c.ToString ());
MemoryStream expected = new MemoryStream ();
MemoryStream expUnicode = new MemoryStream ();
//build expected result for UrlEncode
-- for (int i = 0; i<bIn.Length; i++)
-- UrlEncodeChar ((char)bIn[i], expected, false);
++ for (int i = 0; i < bIn.Length; i++)
++ UrlEncodeChar ((char) bIn [i], expected, false);
//build expected result for UrlEncodeUnicode
UrlEncodeChar (c, expUnicode, true);
-- Assert.AreEqual (Encoding.ASCII.GetString(expected.ToArray()), HttpUtility.UrlEncode (c.ToString()),
-- "UrlEncode "+c.ToString());
-- Assert.AreEqual (Encoding.ASCII.GetString(expUnicode.ToArray()), HttpUtility.UrlEncodeUnicode (c.ToString()),
-- "UrlEncodeUnicode "+c.ToString());
++ Assert.AreEqual (Encoding.ASCII.GetString (expected.ToArray ()), HttpUtility.UrlEncode (c.ToString ()),
++ "UrlEncode " + c.ToString ());
++ Assert.AreEqual (Encoding.ASCII.GetString (expUnicode.ToArray ()), HttpUtility.UrlEncodeUnicode (c.ToString ()),
++ "UrlEncodeUnicode " + c.ToString ());
}
}
#if NET_1_1
[Test]
-- public void UrlPathEncode () {
++ public void UrlPathEncode ()
++ {
++ Assert.AreEqual (null, HttpUtility.UrlPathEncode (null), "#A1-1");
++ Assert.AreEqual (String.Empty, HttpUtility.UrlPathEncode (String.Empty), "#A1-2");
++
for (char c = char.MinValue; c < char.MaxValue; c++) {
MemoryStream expected = new MemoryStream ();
UrlPathEncodeChar (c, expected);
Assert.AreEqual (exp, act, "UrlPathEncode " + c.ToString ());
}
}
-- [Test]
-- public void UrlPathEncode2()
-- {
-- string s = "default.xxx?sdsd=sds";
-- string s2 = HttpUtility.UrlPathEncode(s);
-- Assert.AreEqual(s, s2, "UrlPathEncode " + s);
-- }
++ [Test]
++ public void UrlPathEncode2 ()
++ {
++ string s = "default.xxx?sdsd=sds";
++ string s2 = HttpUtility.UrlPathEncode (s);
++ Assert.AreEqual (s, s2, "UrlPathEncode " + s);
++ }
#endif
--
++
#if NET_2_0
[Test]
#if TARGET_JVM
public void ParseQueryString ()
{
ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value"), "#1",
-- new string[]{"name"}, new string[][]{new string[]{"value"}});
++ new string [] { "name" }, new string [] [] { new string [] { "value" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value&foo=bar"), "#2",
-- new string[]{"name", "foo"}, new string[][]{new string[]{"value"}, new string[]{"bar"}});
++ new string [] { "name", "foo" }, new string [] [] { new string [] { "value" }, new string [] { "bar" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value&name=bar"), "#3",
-- new string[]{"name"}, new string[][]{new string[]{"value", "bar"}});
++ new string [] { "name" }, new string [] [] { new string [] { "value", "bar" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("value"), "#4",
-- new string[] {null}, new string[][]{new string[]{"value"}});
++ new string [] { null }, new string [] [] { new string [] { "value" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value&bar"), "#5",
-- new string[]{"name", null}, new string[][]{new string[]{"value"}, new string[]{"bar"}});
++ new string [] { "name", null }, new string [] [] { new string [] { "value" }, new string [] { "bar" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("bar&name=value"), "#6",
-- new string[]{null, "name"}, new string[][]{new string[]{"bar"}, new string[]{"value"}});
++ new string [] { null, "name" }, new string [] [] { new string [] { "bar" }, new string [] { "value" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("value&bar"), "#7",
-- new string[]{null}, new string[][]{new string[]{"value", "bar"}});
++ new string [] { null }, new string [] [] { new string [] { "value", "bar" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString (""), "#8",
-- new string[0], new string[0][]);
++ new string [0], new string [0] []);
ParseQueryString_Helper (HttpUtility.ParseQueryString ("="), "#9",
-- new string[]{""}, new string[][]{new string[]{""}});
++ new string [] { "" }, new string [] [] { new string [] { "" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("&"), "#10",
-- new string[]{null}, new string[][]{new string[]{"", ""}});
++ new string [] { null }, new string [] [] { new string [] { "", "" } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("?value"), "#11",
-- new string[]{null}, new string[][]{new string[]{"value"}});
++ new string [] { null }, new string [] [] { new string [] { "value" } });
try {
HttpUtility.ParseQueryString (null);
Assert.AreEqual (typeof (ArgumentNullException), e.GetType (), "#13");
}
-- string str = new string (new char[] {'\u304a', '\u75b2', '\u308c', '\u69d8', '\u3067', '\u3059'});
++ string str = new string (new char [] { '\u304a', '\u75b2', '\u308c', '\u69d8', '\u3067', '\u3059' });
string utf8url = HttpUtility.UrlEncode (str, Encoding.UTF8);
ParseQueryString_Helper (HttpUtility.ParseQueryString (utf8url + "=" + utf8url), "#14",
-- new string[]{str}, new string[][]{new string[] {str}});
++ new string [] { str }, new string [] [] { new string [] { str } });
ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value=test"), "#15",
-- new string[]{"name"}, new string[][]{new string[]{"value=test"}});
++ new string [] { "name" }, new string [] [] { new string [] { "value=test" } });
}
-- static void ParseQueryString_Helper (NameValueCollection nvc, string msg, string[] keys, string[][] values)
++ static void ParseQueryString_Helper (NameValueCollection nvc, string msg, string [] keys, string [] [] values)
{
Assert.AreEqual (keys.Length, nvc.Count, msg + "[Count]");
-- for (int i = 0; i < keys.Length; i ++) {
-- Assert.AreEqual (keys[i], nvc.GetKey (i), msg + "[Key]");
-- string[] tmp = nvc.GetValues (i);
-- Assert.AreEqual (values[i].Length, tmp.Length, msg + "[ValueCount]");
-- for (int q = 0; q < values[i].Length; q++)
-- Assert.AreEqual (values[i][q], tmp[q], msg + "[Value]");
++ for (int i = 0; i < keys.Length; i++) {
++ Assert.AreEqual (keys [i], nvc.GetKey (i), msg + "[Key]");
++ string [] tmp = nvc.GetValues (i);
++ Assert.AreEqual (values [i].Length, tmp.Length, msg + "[ValueCount]");
++ for (int q = 0; q < values [i].Length; q++)
++ Assert.AreEqual (values [i] [q], tmp [q], msg + "[Value]");
}
}
#endif
++ string [] decoding_pairs = {
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅  εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ⟨«←⇐⌈“≤⌊∗◊‎‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ"√⟩»→⇒⌉”ℜ®⌋ρΡ‏›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ‍‌",
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅ εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ›’‚šŠ⋅§σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ",
++ @"á?dCO+6Mk'2RÁT148quH^^=972 â#Âjs""{1LZz)U´u@Rv-05n Læ3x}Æ!à,=*-J*À=P|BℵY<g?cg>jB)αΑ9#4V`)|&J/n&JVK56X\2q*F∧Js∠6k6å""Å?rGt≈\F <9IM{s-ã(ShKÃw/[%,ksf93'kä+b$@Q{5ÄUo„aN~'ycb>VKGcjoβoR8""%B`LΒI7g""k5]A>^B¦lllUPg5#b•8Pw,bwSiY ""5]a∩_R@m&D+Lz""dKLTçKH&I}6)_QÇmS%BZV/*Xo¸s5[¢-$|)|L&5~χY/3cdUrnΧ8ˆ&)@KU@scEW2I♣p2,US7f>&m!F≅Fr9A%,Ci'y[]F+©PY↵FeCrQI<:pPP~;>∪¤y J#R&%%i†Ow,‡T↓KpY`WSAo$i:r⇓']=°k12&UI@_δ(9xDΔdz♦RJdB""F^Y}g÷2kbZ2>@yBfué9!9J(vÉ\TwTS2X5iêSLWaTMQE]e&ÊjW{\#JAh{Ua=è5È6/GY∅U n: dcSfεΕ1Yoi?X≡.-s!n|i9U?3:6η+|6Ηha?>fm!v,ðc;Ky]88Ð4T@qO#.ë@Kl3%ËX-VvUoE& €o9T:r8\||^ha;∃1;/BMT*xJ(a>BƒbH'-TH!6NrP∀n½5Fqvq_e9_""XJ¼vmLXTtu:TVZ,¾syl;qEe:b$5j⁄b Hg%Tγ[ΓH≥>{1wT↔o6i~jjKC02⇔Q4i6m(2tpl♥iQj!…4le""4} Lv5{CsíD*u]jÍs}#br=îfhΡ_B:|ìk2U7lZ;_sI\c]Ìsℑ T!5h"".um9ctz∞ YDL∫b(S^ιbCmΙ_L(\-F¿m9g.h$^HSv∈cWH#>ïm0ÏKtgRE3c5@0&κT[2?\>T^H**Κ=^6 [λumΛ[3wQ5gT?H(Bo\/⟨6car8P@AjF4e|b«397jxG:m←U~?~""f⇐`O9iwJ#⌈L:q-* !V“os)Wq6S{t≤=80A⌊#tS6∗x`g6a>]U-b◊SHb/-]‎m9dm""/d<;xR)4‹jrb/,q‘RW}n2shoM11D|<{}*]WPE#d#¯—yhT kµ·`f~o−{Kmfμd7fmtΜPT@OOrzj∇y ;M01XyI: +l<–x5|a>62y≠GNKJQjmj3∋Az¬?V∉,<⊄R]LcñkV:Ñ9LLf&Z%`d-H^Lνv_yXhtΝR1yuF!ój3]zOwQf_YtT9tÓ}s]&1TôÔ2lENœ:Rp^X+tPNL.Œx0 ?c3ZPò3Ò‾@nEωuK-*HjL-h5zΩ~xοFNQ8D#{ΟYj|]'LX⊕ie-Y∨ª$*.cºVM7KQ.b]hmV øx{R>J-D_0vØHpõL'IGÕ`⊗E ö>KNCmÖO2dH_&jd^ >2¶U%""_n∂U>F‰?TSz0~~⊥!p@G~bH^Eφdg)AΦ J<<j_,7Q)dEs,πZΠ_B<@%.&?70ϖ9Y^C|VRPrb4}±Yn=9=SQ;`}(e%£y;6|RN;|w′AH=XXf″∏DGf6ol∝ψ]UXZU\vzW4Ψe`NY[vrvs"xay√[@\scKIznodD<s⟩PB C)<itm+»{t-L→s^^x<:&sh3⇒p^s6Y~3Csw=⌉_pKnhDNTmA*p”]yG6;,ZuPxℜxsd®`hXlUn~(pK=N:^⌋OS""P{%j-Wjbx.wρts^Ρr$h<:u^‏Vj}\?7SIauBh›u[ !rto/[UHog’xe6gY<24BY.‚`ZNR}šuY{Gg;FŠ⋅az4TlWKYbJ.h§c`9FrP­5_)σwx.nP}z@ΣNP9-$@j5ς∼'ogIt:.@Gul♠""p\\rH[)⊂Om/|3G+BQe⊆5s!f/O9SA\RJkv∑GOFMAXu⊃W¹²L`r""}u/n³.ouLC⊇(fß{τB%e [Τ$DD>kIdV#X`?^\∴|S?Wθx)2P.![^5ΘzqF""pjϑ#BE1u? GGG>(EQEþ!""y1r/Þm&@[\mw[kNR˜|1G#i[(×X<UotTID uY™sWW+TbxYúkQXr!H6Ú~0TiH1POP↑(CRZttz\EY<⇑&bN7ki|ûr,3j!e$kJE&Z$zÛ5{0[bvD""[<P)ù;1EeRSrz/gY/Ù/1 S`I*q8:Z-¨%N)WϒO[2P9 ?υOΥtüÜVLq℘2""(Z'~~""uiXξNCqΞ9)S]^v 3ýx""|2&$`GÝ<&Nr¥[3NB5fÿ c""MzMw3(;""sŸζ{!Ζoevp1'j(E`vJ‍Si‌gw>yc*U",
++ @"á?dCO+6Mk'2RÁT148quH^^=972 â#Âjs""{1LZz)U´u@Rv-05n Læ3x}Æ!à,=*-J*À=P|BℵY<g?cg>jB)αΑ9#4V`)|&J/n&JVK56X\2q*F∧Js∠6k6å""Å?rGt≈\F <9IM{s-ã(ShKÃw/[%,ksf93'kä+b$@Q{5ÄUo„aN~'ycb>VKGcjoβoR8""%B`LΒI7g""k5]A>^B¦lllUPg5#b•8Pw,bwSiY ""5]a∩_R@m&D+Lz""dKLTçKH&I}6)_QÇmS%BZV/*Xo¸s5[¢-$|)|L&5~χY/3cdUrnΧ8ˆ&)@KU@scEW2I♣p2,US7f>&m!F≅Fr9A%,Ci'y[]F+©PY↵FeCrQI<:pPP~;>∪¤y J#R&%%i†Ow,‡T↓KpY`WSAo$i:r⇓']=°k12&UI@_δ(9xDΔdz♦RJdB""F^Y}g÷2kbZ2>@yBfué9!9J(vÉ\TwTS2X5iêSLWaTMQE]e&ÊjW{\#JAh{Ua=è5È6/GY∅U n: dcSfεΕ1Yoi?X≡.-s!n|i9U?3:6η+|6Ηha?>fm!v,ðc;Ky]88Ð4T@qO#.ë@Kl3%ËX-VvUoE& €o9T:r8\||^ha;∃1;/BMT*xJ(a>BƒbH'-TH!6NrP∀n½5Fqvq_e9_""XJ¼vmLXTtu:TVZ,¾syl;qEe:b$5j⁄b Hg%Tγ[ΓH≥>{1wT↔o6i~jjKC02⇔Q4i6m(2tpl♥iQj!…4le""4} Lv5{CsíD*u]jÍs}#br=îfhΡ_B:|ìk2U7lZ;_sI\c]Ìsℑ T!5h"".um9ctz∞ YDL∫b(S^ιbCmΙ_L(\-F¿m9g.h$^HSv∈cWH#>ïm0ÏKtgRE3c5@0&κT[2?\>T^H**Κ=^6 [λumΛ[3wQ5gT?H(Bo\/〈6car8P@AjF4e|b«397jxG:m←U~?~""f⇐`O9iwJ#⌈L:q-* !V“os)Wq6S{t≤=80A⌊#tS6∗x`g6a>]U-b◊SHb/-]m9dm""/d<;xR)4‹jrb/,q‘RW}n2shoM11D|<{}*]WPE#d#¯—yhT kµ·`f~o−{Kmfμd7fmtΜPT@OOrzj∇y ;M01XyI: +l<–x5|a>62y≠GNKJQjmj3∋Az¬?V∉,<⊄R]LcñkV:Ñ9LLf&Z%`d-H^Lνv_yXhtΝR1yuF!ój3]zOwQf_YtT9tÓ}s]&1TôÔ2lENœ:Rp^X+tPNL.Œx0 ?c3ZPò3Ò‾@nEωuK-*HjL-h5zΩ~xοFNQ8D#{ΟYj|]'LX⊕ie-Y∨ª$*.cºVM7KQ.b]hmV øx{R>J-D_0vØHpõL'IGÕ`⊗E ö>KNCmÖO2dH_&jd^ >2¶U%""_n∂U>F‰?TSz0~~⊥!p@G~bH^Eφdg)AΦ J<<j_,7Q)dEs,πZΠ_B<@%.&?70ϖ9Y^C|VRPrb4}±Yn=9=SQ;`}(e%£y;6|RN;|w′AH=XXf″∏DGf6ol∝ψ]UXZU\vzW4Ψe`NY[vrvs""xay√[@\scKIznodD<s〉PB C)<itm+»{t-L→s^^x<:&sh3⇒p^s6Y~3Csw=⌉_pKnhDNTmA*p”]yG6;,ZuPxℜxsd®`hXlUn~(pK=N:^⌋OS""P{%j-Wjbx.wρts^Ρr$h<:u^Vj}\?7SIauBh›u[ !rto/[UHog’xe6gY<24BY.‚`ZNR}šuY{Gg;FŠ⋅az4TlWKYbJ.h§c`9FrP5_)σwx.nP}z@ΣNP9-$@j5ς∼'ogIt:.@Gul♠""p\\rH[)⊂Om/|3G+BQe⊆5s!f/O9SA\RJkv∑GOFMAXu⊃W¹²L`r""}u/n³.ouLC⊇(fß{τB%e [Τ$DD>kIdV#X`?^\∴|S?Wθx)2P.![^5ΘzqF""pjϑ#BE1u? GGG>(EQEþ!""y1r/Þm&@[\mw[kNR˜|1G#i[(×X<UotTID uY™sWW+TbxYúkQXr!H6Ú~0TiH1POP↑(CRZttz\EY<⇑&bN7ki|ûr,3j!e$kJE&Z$zÛ5{0[bvD""[<P)ù;1EeRSrz/gY/Ù/1 S`I*q8:Z-¨%N)WϒO[2P9 ?υOΥtüÜVLq℘2""(Z'~~""uiXξNCqΞ9)S]^v 3ýx""|2&$`GÝ<&Nr¥[3NB5fÿ c""MzMw3(;""sŸζ{!Ζoevp1'j(E`vJSigw>yc*U",
++ @"áÁâ´æÆàÀ&alefsym&alpha&Alpha&&and&angåÅ&asympãÃäÄ&bdquo&beta&Beta¦&bull&capçǸ¢&chi&Chi&circ&clubs&cong©&crarr&cup¤&dagger&Dagger&darr&dArr°&delta&Delta&diams÷éÉêÊèÈ&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&EtaðÐëË&euro&exist&fnof&forall½¼¾&frasl&gamma&Gamma&ge>&harr&hArr&hearts&hellipíÍîΡìÌ&image&infin&int&iota&Iota¿&isinïÏ&kappa&Kappa&lambda&Lambda&lang«&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo<¯&mdashµ·&minus&mu&Mu&nabla &ndash&ne&ni¬¬in&nsubñÑ&nu&NuóÓôÔ&oelig&OEligòÒ&oline&omega&Omega&omicron&Omicron&oplus&orªºøØõÕ&otimesöÖ¶&part&permil&perp&phi&Phi&pi&Pi&piv±£&prime&Prime&prod&prop&psi&Psi"&radic&rang»&rarr&rArr&rceil&rdquo&real®&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot§­&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup¹²³&supeß&tau&Tau&there4&theta&Theta&thetasym&thinspþÞ&tilde×&tradeúÚ&uarr&uArrûÛùÙ¨&upsih&upsilon&UpsilonüÜ&weierp&xi&XiýÝ¥ÿ&Yuml&zeta&Zeta&zwj&zwnj",
++ @"áÁâ´æÆàÀ&alefsym&alpha&Alpha&&and&angåÅ&asympãÃäÄ&bdquo&beta&Beta¦&bull&capçǸ¢&chi&Chi&circ&clubs&cong©&crarr&cup¤&dagger&Dagger&darr&dArr°&delta&Delta&diams÷éÉêÊèÈ&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&EtaðÐëË&euro&exist&fnof&forall½¼¾&frasl&gamma&Gamma&ge>&harr&hArr&hearts&hellipíÍîΡìÌ&image&infin&int&iota&Iota¿&isinïÏ&kappa&Kappa&lambda&Lambda&lang«&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo<¯&mdashµ·&minus&mu&Mu&nabla &ndash&ne&ni¬¬in&nsubñÑ&nu&NuóÓôÔ&oelig&OEligòÒ&oline&omega&Omega&omicron&Omicron&oplus&orªºøØõÕ&otimesöÖ¶&part&permil&perp&phi&Phi&pi&Pi&piv±£&prime&Prime&prod&prop&psi&Psi"&radic&rang»&rarr&rArr&rceil&rdquo&real®&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot§­&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup¹²³&supeß&tau&Tau&there4&theta&Theta&thetasym&thinspþÞ&tilde×&tradeúÚ&uarr&uArrûÛùÙ¨&upsih&upsilon&UpsilonüÜ&weierp&xi&XiýÝ¥ÿ&Yuml&zeta&Zeta&zwj&zwnj",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @"�	

 ",
++#if NET_4_0
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++#else
++ "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++#endif
++ @"�	

 ",
++#if NET_4_0
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++#else
++ "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++#endif
++@" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ " ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++};
++ string [] encoding_pairs = {
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅ εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ›’‚šŠ⋅§σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ",
++ @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅ εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ"√〉»→⇒⌉”ℜ®⌋ρΡ›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ",
++ @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N""åzcWM'z""gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x""ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ""+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT""qAκ*/ΚλN>j}""WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[""3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\""µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S"",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI""Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu""ο:Mz$(""joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|""yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£""'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO""'4""/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6oTxP""""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+59.W\v]GGtKvCC0`A",
++#if NET_4_0
++ @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N"åzcWM'z"gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x"ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ"+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT"qAκ*/ΚλN>j}"WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8["3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\"µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI"Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu"ο:Mz$("joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|"yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£"'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO"'4"/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6oTxP""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'­qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+59.W\v]GGtKvCC0`A",
++#else
++ @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N"åzcWM'z"gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x"ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ"+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT"qAκ*/ΚλN>j}"WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8["3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\"µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI"Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu"ο:Mz$("joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|"yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£"'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO"'4"/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6oTxP""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'­qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+59.W\v]GGtKvCC0`A",
++#endif
++ @"áÁâ´æÆàÀ&alefsym&alpha&Alpha&&and&angåÅ&asympãÃäÄ&bdquo&beta&Beta¦&bull&capçǸ¢&chi&Chi&circ&clubs&cong©&crarr&cup¤&dagger&Dagger&darr&dArr°&delta&Delta&diams÷éÉêÊèÈ&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&EtaðÐëË&euro&exist&fnof&forall½¼¾&frasl&gamma&Gamma&ge>&harr&hArr&hearts&hellipíÍîΡìÌ&image&infin&int&iota&Iota¿&isinïÏ&kappa&Kappa&lambda&Lambda&lang«&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo<¯&mdashµ·&minus&mu&Mu&nabla &ndash&ne&ni¬¬in&nsubñÑ&nu&NuóÓôÔ&oelig&OEligòÒ&oline&omega&Omega&omicron&Omicron&oplus&orªºøØõÕ&otimesöÖ¶&part&permil&perp&phi&Phi&pi&Pi&piv±£&prime&Prime&prod&prop&psi&Psi"&radic&rang»&rarr&rArr&rceil&rdquo&real®&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot§­&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup¹²³&supeß&tau&Tau&there4&theta&Theta&thetasym&thinspþÞ&tilde×&tradeúÚ&uarr&uArrûÛùÙ¨&upsih&upsilon&UpsilonüÜ&weierp&xi&XiýÝ¥ÿ&Yuml&zeta&Zeta&zwj&zwnj",
++ @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
++ @" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ "&#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ "�\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ "&#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
++ @" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++ @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
++};
++
}
}
$(CSCOMPILE) $(APPLICATION_ASSEMBLY_MCS_FLAGS) $(APPLICATION_ASSEMBLY_SOURCES) -target:library -out:$(APPLICATION_ASSEMBLY)
bin/.stamp:
-- install -d -m 755 ApplicationPreStartMethods/bin/
-- touch ApplicationPreStartMethods/bin/.stamp
++ install -d -m 755 bin/
++ touch bin/.stamp
endif
clean: