1 // 2 // Authors: 3 // Patrik Torstensson (Patrik.Torstensson@labs2.com) 4 // Wictor Wilén (decode/encode functions) (wictor@ibizkit.se) 5 // Tim Coleman (tim@timcoleman.com) 6 // Gonzalo Paniagua Javier (gonzalo@ximian.com) 7 8 // Marek Habersack <mhabersack@novell.com> 9 // 10 // (C) 2005-2010 Novell, Inc (http://novell.com/) 11 // 12 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining 15 // a copy of this software and associated documentation files (the 16 // "Software"), to deal in the Software without restriction, including 17 // without limitation the rights to use, copy, modify, merge, publish, 18 // distribute, sublicense, and/or sell copies of the Software, and to 19 // permit persons to whom the Software is furnished to do so, subject to 20 // the following conditions: 21 // 22 // The above copyright notice and this permission notice shall be 23 // included in all copies or substantial portions of the Software. 24 // 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 // 33 using System; 34 using System.Collections.Generic; 35 using System.Configuration; 36 using System.IO; 37 using System.Text; 38 #if !NO_SYSTEM_WEB_DEPENDENCY && !MOBILE 39 using System.Web.Configuration; 40 #endif 41 42 namespace System.Web.Util 43 { 44 public 45 class HttpEncoder 46 { 47 static char [] hexChars = "0123456789abcdef".ToCharArray (); 48 static object entitiesLock = new object (); 49 static SortedDictionary <string, char> entities; 50 static Lazy <HttpEncoder> defaultEncoder; 51 static Lazy <HttpEncoder> currentEncoderLazy; 52 static HttpEncoder currentEncoder; 53 54 static IDictionary <string, char> Entities { 55 get { 56 lock (entitiesLock) { 57 if (entities == null) 58 InitEntities (); 59 60 return entities; 61 } 62 } 63 } 64 65 public static HttpEncoder Current { 66 get { 67 if (currentEncoder == null) 68 currentEncoder = currentEncoderLazy.Value; 69 return currentEncoder; 70 } 71 set { 72 if (value == null) 73 throw new ArgumentNullException ("value"); 74 currentEncoder = value; 75 } 76 } 77 78 public static HttpEncoder Default { 79 get { 80 return defaultEncoder.Value; 81 } 82 } 83 HttpEncoder()84 static HttpEncoder () 85 { 86 defaultEncoder = new Lazy <HttpEncoder> (() => new HttpEncoder ()); 87 currentEncoderLazy = new Lazy <HttpEncoder> (new Func <HttpEncoder> (GetCustomEncoderFromConfig)); 88 } 89 HttpEncoder()90 public HttpEncoder () 91 { 92 } 93 protected internal virtual HeaderNameValueEncode(string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue)94 void HeaderNameValueEncode (string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue) 95 { 96 if (String.IsNullOrEmpty (headerName)) 97 encodedHeaderName = headerName; 98 else 99 encodedHeaderName = EncodeHeaderString (headerName); 100 101 if (String.IsNullOrEmpty (headerValue)) 102 encodedHeaderValue = headerValue; 103 else 104 encodedHeaderValue = EncodeHeaderString (headerValue); 105 } 106 StringBuilderAppend(string s, ref StringBuilder sb)107 static void StringBuilderAppend (string s, ref StringBuilder sb) 108 { 109 if (sb == null) 110 sb = new StringBuilder (s); 111 else 112 sb.Append (s); 113 } 114 EncodeHeaderString(string input)115 static string EncodeHeaderString (string input) 116 { 117 StringBuilder sb = null; 118 119 for (int i = 0; i < input.Length; i++) { 120 char ch = input [i]; 121 122 if ((ch < 32 && ch != 9) || ch == 127) 123 StringBuilderAppend (String.Format ("%{0:x2}", (int)ch), ref sb); 124 } 125 126 if (sb != null) 127 return sb.ToString (); 128 129 return input; 130 } HtmlAttributeEncode(string value, TextWriter output)131 protected internal virtual void HtmlAttributeEncode (string value, TextWriter output) 132 { 133 134 if (output == null) 135 throw new ArgumentNullException ("output"); 136 137 if (String.IsNullOrEmpty (value)) 138 return; 139 140 output.Write (HtmlAttributeEncode (value)); 141 } 142 HtmlDecode(string value, TextWriter output)143 protected internal virtual void HtmlDecode (string value, TextWriter output) 144 { 145 if (output == null) 146 throw new ArgumentNullException ("output"); 147 148 output.Write (HtmlDecode (value)); 149 } 150 HtmlEncode(string value, TextWriter output)151 protected internal virtual void HtmlEncode (string value, TextWriter output) 152 { 153 if (output == null) 154 throw new ArgumentNullException ("output"); 155 156 output.Write (HtmlEncode (value)); 157 } 158 UrlEncode(byte[] bytes, int offset, int count)159 protected internal virtual byte[] UrlEncode (byte[] bytes, int offset, int count) 160 { 161 return UrlEncodeToBytes (bytes, offset, count); 162 } 163 GetCustomEncoderFromConfig()164 static HttpEncoder GetCustomEncoderFromConfig () 165 { 166 #if MOBILE || NO_SYSTEM_WEB_DEPENDENCY 167 return defaultEncoder.Value; 168 #else 169 var cfg = HttpRuntime.Section; 170 string typeName = cfg.EncoderType; 171 172 if (String.Compare (typeName, "System.Web.Util.HttpEncoder", StringComparison.OrdinalIgnoreCase) == 0) 173 return Default; 174 175 Type t = Type.GetType (typeName, false); 176 if (t == null) 177 throw new ConfigurationErrorsException (String.Format ("Could not load type '{0}'.", typeName)); 178 179 if (!typeof (HttpEncoder).IsAssignableFrom (t)) 180 throw new ConfigurationErrorsException ( 181 String.Format ("'{0}' is not allowed here because it does not extend class 'System.Web.Util.HttpEncoder'.", typeName) 182 ); 183 184 return Activator.CreateInstance (t, false) as HttpEncoder; 185 #endif 186 } 187 protected internal virtual UrlPathEncode(string value)188 string UrlPathEncode (string value) 189 { 190 if (String.IsNullOrEmpty (value)) 191 return value; 192 193 MemoryStream result = new MemoryStream (); 194 int length = value.Length; 195 for (int i = 0; i < length; i++) 196 UrlPathEncodeChar (value [i], result); 197 198 return Encoding.ASCII.GetString (result.ToArray ()); 199 } 200 UrlEncodeToBytes(byte[] bytes, int offset, int count)201 internal static byte[] UrlEncodeToBytes (byte[] bytes, int offset, int count) 202 { 203 if (bytes == null) 204 throw new ArgumentNullException ("bytes"); 205 206 int blen = bytes.Length; 207 if (blen == 0) 208 return new byte [0]; 209 210 if (offset < 0 || offset >= blen) 211 throw new ArgumentOutOfRangeException("offset"); 212 213 if (count < 0 || count > blen - offset) 214 throw new ArgumentOutOfRangeException("count"); 215 216 MemoryStream result = new MemoryStream (count); 217 int end = offset + count; 218 for (int i = offset; i < end; i++) 219 UrlEncodeChar ((char)bytes [i], result, false); 220 221 return result.ToArray(); 222 } 223 HtmlEncode(string s)224 internal static string HtmlEncode (string s) 225 { 226 if (s == null) 227 return null; 228 229 if (s.Length == 0) 230 return String.Empty; 231 232 bool needEncode = false; 233 for (int i = 0; i < s.Length; i++) { 234 char c = s [i]; 235 if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159 236 || c == '\'' 237 ) { 238 needEncode = true; 239 break; 240 } 241 } 242 243 if (!needEncode) 244 return s; 245 246 StringBuilder output = new StringBuilder (); 247 int len = s.Length; 248 249 for (int i = 0; i < len; i++) { 250 char ch = s [i]; 251 switch (ch) { 252 case '&' : 253 output.Append ("&"); 254 break; 255 case '>' : 256 output.Append (">"); 257 break; 258 case '<' : 259 output.Append ("<"); 260 break; 261 case '"' : 262 output.Append ("""); 263 break; 264 case '\'': 265 output.Append ("'"); 266 break; 267 case '\uff1c': 268 output.Append ("<"); 269 break; 270 271 case '\uff1e': 272 output.Append (">"); 273 break; 274 275 default: 276 if (ch > 159 && ch < 256) { 277 output.Append ("&#"); 278 output.Append (((int) ch).ToString (Helpers.InvariantCulture)); 279 output.Append (";"); 280 } else 281 output.Append (ch); 282 break; 283 } 284 } 285 286 return output.ToString (); 287 } 288 HtmlAttributeEncode(string s)289 internal static string HtmlAttributeEncode (string s) 290 { 291 if (String.IsNullOrEmpty (s)) 292 return String.Empty; 293 bool needEncode = false; 294 for (int i = 0; i < s.Length; i++) { 295 char c = s [i]; 296 if (c == '&' || c == '"' || c == '<' 297 || c == '\'' 298 ) { 299 needEncode = true; 300 break; 301 } 302 } 303 304 if (!needEncode) 305 return s; 306 307 StringBuilder output = new StringBuilder (); 308 int len = s.Length; 309 310 for (int i = 0; i < len; i++) { 311 char ch = s [i]; 312 switch (ch) { 313 case '&' : 314 output.Append ("&"); 315 break; 316 case '"' : 317 output.Append ("""); 318 break; 319 case '<': 320 output.Append ("<"); 321 break; 322 case '\'': 323 output.Append ("'"); 324 break; 325 default: 326 output.Append (ch); 327 break; 328 } 329 } 330 331 return output.ToString(); 332 } 333 HtmlDecode(string s)334 internal static string HtmlDecode (string s) 335 { 336 if (s == null) 337 return null; 338 339 if (s.Length == 0) 340 return String.Empty; 341 342 if (s.IndexOf ('&') == -1) 343 return s; 344 StringBuilder rawEntity = new StringBuilder (); 345 StringBuilder entity = new StringBuilder (); 346 StringBuilder output = new StringBuilder (); 347 int len = s.Length; 348 // 0 -> nothing, 349 // 1 -> right after '&' 350 // 2 -> between '&' and ';' but no '#' 351 // 3 -> '#' found after '&' and getting numbers 352 int state = 0; 353 int number = 0; 354 bool is_hex_value = false; 355 bool have_trailing_digits = false; 356 357 for (int i = 0; i < len; i++) { 358 char c = s [i]; 359 if (state == 0) { 360 if (c == '&') { 361 entity.Append (c); 362 rawEntity.Append (c); 363 state = 1; 364 } else { 365 output.Append (c); 366 } 367 continue; 368 } 369 370 if (c == '&') { 371 state = 1; 372 if (have_trailing_digits) { 373 entity.Append (number.ToString (Helpers.InvariantCulture)); 374 have_trailing_digits = false; 375 } 376 377 output.Append (entity.ToString ()); 378 entity.Length = 0; 379 entity.Append ('&'); 380 continue; 381 } 382 383 if (state == 1) { 384 if (c == ';') { 385 state = 0; 386 output.Append (entity.ToString ()); 387 output.Append (c); 388 entity.Length = 0; 389 } else { 390 number = 0; 391 is_hex_value = false; 392 if (c != '#') { 393 state = 2; 394 } else { 395 state = 3; 396 } 397 entity.Append (c); 398 rawEntity.Append (c); 399 } 400 } else if (state == 2) { 401 entity.Append (c); 402 if (c == ';') { 403 string key = entity.ToString (); 404 if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2))) 405 key = Entities [key.Substring (1, key.Length - 2)].ToString (); 406 407 output.Append (key); 408 state = 0; 409 entity.Length = 0; 410 rawEntity.Length = 0; 411 } 412 } else if (state == 3) { 413 if (c == ';') { 414 if (number == 0) 415 output.Append (rawEntity.ToString () + ";"); 416 else 417 if (number > 65535) { 418 output.Append ("&#"); 419 output.Append (number.ToString (Helpers.InvariantCulture)); 420 output.Append (";"); 421 } else { 422 output.Append ((char) number); 423 } 424 state = 0; 425 entity.Length = 0; 426 rawEntity.Length = 0; 427 have_trailing_digits = false; 428 } else if (is_hex_value && Uri.IsHexDigit(c)) { 429 number = number * 16 + Uri.FromHex(c); 430 have_trailing_digits = true; 431 rawEntity.Append (c); 432 } else if (Char.IsDigit (c)) { 433 number = number * 10 + ((int) c - '0'); 434 have_trailing_digits = true; 435 rawEntity.Append (c); 436 } else if (number == 0 && (c == 'x' || c == 'X')) { 437 is_hex_value = true; 438 rawEntity.Append (c); 439 } else { 440 state = 2; 441 if (have_trailing_digits) { 442 entity.Append (number.ToString (Helpers.InvariantCulture)); 443 have_trailing_digits = false; 444 } 445 entity.Append (c); 446 } 447 } 448 } 449 450 if (entity.Length > 0) { 451 output.Append (entity.ToString ()); 452 } else if (have_trailing_digits) { 453 output.Append (number.ToString (Helpers.InvariantCulture)); 454 } 455 return output.ToString (); 456 } 457 NotEncoded(char c)458 internal static bool NotEncoded (char c) 459 { 460 return (c == '!' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_' 461 ); 462 } 463 UrlEncodeChar(char c, Stream result, bool isUnicode)464 internal static void UrlEncodeChar (char c, Stream result, bool isUnicode) { 465 if (c > 255) { 466 //FIXME: what happens when there is an internal error? 467 //if (!isUnicode) 468 // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256"); 469 int idx; 470 int i = (int) c; 471 472 result.WriteByte ((byte)'%'); 473 result.WriteByte ((byte)'u'); 474 idx = i >> 12; 475 result.WriteByte ((byte)hexChars [idx]); 476 idx = (i >> 8) & 0x0F; 477 result.WriteByte ((byte)hexChars [idx]); 478 idx = (i >> 4) & 0x0F; 479 result.WriteByte ((byte)hexChars [idx]); 480 idx = i & 0x0F; 481 result.WriteByte ((byte)hexChars [idx]); 482 return; 483 } 484 485 if (c > ' ' && NotEncoded (c)) { 486 result.WriteByte ((byte)c); 487 return; 488 } 489 if (c==' ') { 490 result.WriteByte ((byte)'+'); 491 return; 492 } 493 if ( (c < '0') || 494 (c < 'A' && c > '9') || 495 (c > 'Z' && c < 'a') || 496 (c > 'z')) { 497 if (isUnicode && c > 127) { 498 result.WriteByte ((byte)'%'); 499 result.WriteByte ((byte)'u'); 500 result.WriteByte ((byte)'0'); 501 result.WriteByte ((byte)'0'); 502 } 503 else 504 result.WriteByte ((byte)'%'); 505 506 int idx = ((int) c) >> 4; 507 result.WriteByte ((byte)hexChars [idx]); 508 idx = ((int) c) & 0x0F; 509 result.WriteByte ((byte)hexChars [idx]); 510 } 511 else 512 result.WriteByte ((byte)c); 513 } 514 UrlPathEncodeChar(char c, Stream result)515 internal static void UrlPathEncodeChar (char c, Stream result) 516 { 517 if (c < 33 || c > 126) { 518 byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ()); 519 for (int i = 0; i < bIn.Length; i++) { 520 result.WriteByte ((byte) '%'); 521 int idx = ((int) bIn [i]) >> 4; 522 result.WriteByte ((byte) hexChars [idx]); 523 idx = ((int) bIn [i]) & 0x0F; 524 result.WriteByte ((byte) hexChars [idx]); 525 } 526 } 527 else if (c == ' ') { 528 result.WriteByte ((byte) '%'); 529 result.WriteByte ((byte) '2'); 530 result.WriteByte ((byte) '0'); 531 } 532 else 533 result.WriteByte ((byte) c); 534 } 535 InitEntities()536 static void InitEntities () 537 { 538 // Build the hash table of HTML entity references. This list comes 539 // from the HTML 4.01 W3C recommendation. 540 entities = new SortedDictionary <string, char> (StringComparer.Ordinal); 541 542 entities.Add ("nbsp", '\u00A0'); 543 entities.Add ("iexcl", '\u00A1'); 544 entities.Add ("cent", '\u00A2'); 545 entities.Add ("pound", '\u00A3'); 546 entities.Add ("curren", '\u00A4'); 547 entities.Add ("yen", '\u00A5'); 548 entities.Add ("brvbar", '\u00A6'); 549 entities.Add ("sect", '\u00A7'); 550 entities.Add ("uml", '\u00A8'); 551 entities.Add ("copy", '\u00A9'); 552 entities.Add ("ordf", '\u00AA'); 553 entities.Add ("laquo", '\u00AB'); 554 entities.Add ("not", '\u00AC'); 555 entities.Add ("shy", '\u00AD'); 556 entities.Add ("reg", '\u00AE'); 557 entities.Add ("macr", '\u00AF'); 558 entities.Add ("deg", '\u00B0'); 559 entities.Add ("plusmn", '\u00B1'); 560 entities.Add ("sup2", '\u00B2'); 561 entities.Add ("sup3", '\u00B3'); 562 entities.Add ("acute", '\u00B4'); 563 entities.Add ("micro", '\u00B5'); 564 entities.Add ("para", '\u00B6'); 565 entities.Add ("middot", '\u00B7'); 566 entities.Add ("cedil", '\u00B8'); 567 entities.Add ("sup1", '\u00B9'); 568 entities.Add ("ordm", '\u00BA'); 569 entities.Add ("raquo", '\u00BB'); 570 entities.Add ("frac14", '\u00BC'); 571 entities.Add ("frac12", '\u00BD'); 572 entities.Add ("frac34", '\u00BE'); 573 entities.Add ("iquest", '\u00BF'); 574 entities.Add ("Agrave", '\u00C0'); 575 entities.Add ("Aacute", '\u00C1'); 576 entities.Add ("Acirc", '\u00C2'); 577 entities.Add ("Atilde", '\u00C3'); 578 entities.Add ("Auml", '\u00C4'); 579 entities.Add ("Aring", '\u00C5'); 580 entities.Add ("AElig", '\u00C6'); 581 entities.Add ("Ccedil", '\u00C7'); 582 entities.Add ("Egrave", '\u00C8'); 583 entities.Add ("Eacute", '\u00C9'); 584 entities.Add ("Ecirc", '\u00CA'); 585 entities.Add ("Euml", '\u00CB'); 586 entities.Add ("Igrave", '\u00CC'); 587 entities.Add ("Iacute", '\u00CD'); 588 entities.Add ("Icirc", '\u00CE'); 589 entities.Add ("Iuml", '\u00CF'); 590 entities.Add ("ETH", '\u00D0'); 591 entities.Add ("Ntilde", '\u00D1'); 592 entities.Add ("Ograve", '\u00D2'); 593 entities.Add ("Oacute", '\u00D3'); 594 entities.Add ("Ocirc", '\u00D4'); 595 entities.Add ("Otilde", '\u00D5'); 596 entities.Add ("Ouml", '\u00D6'); 597 entities.Add ("times", '\u00D7'); 598 entities.Add ("Oslash", '\u00D8'); 599 entities.Add ("Ugrave", '\u00D9'); 600 entities.Add ("Uacute", '\u00DA'); 601 entities.Add ("Ucirc", '\u00DB'); 602 entities.Add ("Uuml", '\u00DC'); 603 entities.Add ("Yacute", '\u00DD'); 604 entities.Add ("THORN", '\u00DE'); 605 entities.Add ("szlig", '\u00DF'); 606 entities.Add ("agrave", '\u00E0'); 607 entities.Add ("aacute", '\u00E1'); 608 entities.Add ("acirc", '\u00E2'); 609 entities.Add ("atilde", '\u00E3'); 610 entities.Add ("auml", '\u00E4'); 611 entities.Add ("aring", '\u00E5'); 612 entities.Add ("aelig", '\u00E6'); 613 entities.Add ("ccedil", '\u00E7'); 614 entities.Add ("egrave", '\u00E8'); 615 entities.Add ("eacute", '\u00E9'); 616 entities.Add ("ecirc", '\u00EA'); 617 entities.Add ("euml", '\u00EB'); 618 entities.Add ("igrave", '\u00EC'); 619 entities.Add ("iacute", '\u00ED'); 620 entities.Add ("icirc", '\u00EE'); 621 entities.Add ("iuml", '\u00EF'); 622 entities.Add ("eth", '\u00F0'); 623 entities.Add ("ntilde", '\u00F1'); 624 entities.Add ("ograve", '\u00F2'); 625 entities.Add ("oacute", '\u00F3'); 626 entities.Add ("ocirc", '\u00F4'); 627 entities.Add ("otilde", '\u00F5'); 628 entities.Add ("ouml", '\u00F6'); 629 entities.Add ("divide", '\u00F7'); 630 entities.Add ("oslash", '\u00F8'); 631 entities.Add ("ugrave", '\u00F9'); 632 entities.Add ("uacute", '\u00FA'); 633 entities.Add ("ucirc", '\u00FB'); 634 entities.Add ("uuml", '\u00FC'); 635 entities.Add ("yacute", '\u00FD'); 636 entities.Add ("thorn", '\u00FE'); 637 entities.Add ("yuml", '\u00FF'); 638 entities.Add ("fnof", '\u0192'); 639 entities.Add ("Alpha", '\u0391'); 640 entities.Add ("Beta", '\u0392'); 641 entities.Add ("Gamma", '\u0393'); 642 entities.Add ("Delta", '\u0394'); 643 entities.Add ("Epsilon", '\u0395'); 644 entities.Add ("Zeta", '\u0396'); 645 entities.Add ("Eta", '\u0397'); 646 entities.Add ("Theta", '\u0398'); 647 entities.Add ("Iota", '\u0399'); 648 entities.Add ("Kappa", '\u039A'); 649 entities.Add ("Lambda", '\u039B'); 650 entities.Add ("Mu", '\u039C'); 651 entities.Add ("Nu", '\u039D'); 652 entities.Add ("Xi", '\u039E'); 653 entities.Add ("Omicron", '\u039F'); 654 entities.Add ("Pi", '\u03A0'); 655 entities.Add ("Rho", '\u03A1'); 656 entities.Add ("Sigma", '\u03A3'); 657 entities.Add ("Tau", '\u03A4'); 658 entities.Add ("Upsilon", '\u03A5'); 659 entities.Add ("Phi", '\u03A6'); 660 entities.Add ("Chi", '\u03A7'); 661 entities.Add ("Psi", '\u03A8'); 662 entities.Add ("Omega", '\u03A9'); 663 entities.Add ("alpha", '\u03B1'); 664 entities.Add ("beta", '\u03B2'); 665 entities.Add ("gamma", '\u03B3'); 666 entities.Add ("delta", '\u03B4'); 667 entities.Add ("epsilon", '\u03B5'); 668 entities.Add ("zeta", '\u03B6'); 669 entities.Add ("eta", '\u03B7'); 670 entities.Add ("theta", '\u03B8'); 671 entities.Add ("iota", '\u03B9'); 672 entities.Add ("kappa", '\u03BA'); 673 entities.Add ("lambda", '\u03BB'); 674 entities.Add ("mu", '\u03BC'); 675 entities.Add ("nu", '\u03BD'); 676 entities.Add ("xi", '\u03BE'); 677 entities.Add ("omicron", '\u03BF'); 678 entities.Add ("pi", '\u03C0'); 679 entities.Add ("rho", '\u03C1'); 680 entities.Add ("sigmaf", '\u03C2'); 681 entities.Add ("sigma", '\u03C3'); 682 entities.Add ("tau", '\u03C4'); 683 entities.Add ("upsilon", '\u03C5'); 684 entities.Add ("phi", '\u03C6'); 685 entities.Add ("chi", '\u03C7'); 686 entities.Add ("psi", '\u03C8'); 687 entities.Add ("omega", '\u03C9'); 688 entities.Add ("thetasym", '\u03D1'); 689 entities.Add ("upsih", '\u03D2'); 690 entities.Add ("piv", '\u03D6'); 691 entities.Add ("bull", '\u2022'); 692 entities.Add ("hellip", '\u2026'); 693 entities.Add ("prime", '\u2032'); 694 entities.Add ("Prime", '\u2033'); 695 entities.Add ("oline", '\u203E'); 696 entities.Add ("frasl", '\u2044'); 697 entities.Add ("weierp", '\u2118'); 698 entities.Add ("image", '\u2111'); 699 entities.Add ("real", '\u211C'); 700 entities.Add ("trade", '\u2122'); 701 entities.Add ("alefsym", '\u2135'); 702 entities.Add ("larr", '\u2190'); 703 entities.Add ("uarr", '\u2191'); 704 entities.Add ("rarr", '\u2192'); 705 entities.Add ("darr", '\u2193'); 706 entities.Add ("harr", '\u2194'); 707 entities.Add ("crarr", '\u21B5'); 708 entities.Add ("lArr", '\u21D0'); 709 entities.Add ("uArr", '\u21D1'); 710 entities.Add ("rArr", '\u21D2'); 711 entities.Add ("dArr", '\u21D3'); 712 entities.Add ("hArr", '\u21D4'); 713 entities.Add ("forall", '\u2200'); 714 entities.Add ("part", '\u2202'); 715 entities.Add ("exist", '\u2203'); 716 entities.Add ("empty", '\u2205'); 717 entities.Add ("nabla", '\u2207'); 718 entities.Add ("isin", '\u2208'); 719 entities.Add ("notin", '\u2209'); 720 entities.Add ("ni", '\u220B'); 721 entities.Add ("prod", '\u220F'); 722 entities.Add ("sum", '\u2211'); 723 entities.Add ("minus", '\u2212'); 724 entities.Add ("lowast", '\u2217'); 725 entities.Add ("radic", '\u221A'); 726 entities.Add ("prop", '\u221D'); 727 entities.Add ("infin", '\u221E'); 728 entities.Add ("ang", '\u2220'); 729 entities.Add ("and", '\u2227'); 730 entities.Add ("or", '\u2228'); 731 entities.Add ("cap", '\u2229'); 732 entities.Add ("cup", '\u222A'); 733 entities.Add ("int", '\u222B'); 734 entities.Add ("there4", '\u2234'); 735 entities.Add ("sim", '\u223C'); 736 entities.Add ("cong", '\u2245'); 737 entities.Add ("asymp", '\u2248'); 738 entities.Add ("ne", '\u2260'); 739 entities.Add ("equiv", '\u2261'); 740 entities.Add ("le", '\u2264'); 741 entities.Add ("ge", '\u2265'); 742 entities.Add ("sub", '\u2282'); 743 entities.Add ("sup", '\u2283'); 744 entities.Add ("nsub", '\u2284'); 745 entities.Add ("sube", '\u2286'); 746 entities.Add ("supe", '\u2287'); 747 entities.Add ("oplus", '\u2295'); 748 entities.Add ("otimes", '\u2297'); 749 entities.Add ("perp", '\u22A5'); 750 entities.Add ("sdot", '\u22C5'); 751 entities.Add ("lceil", '\u2308'); 752 entities.Add ("rceil", '\u2309'); 753 entities.Add ("lfloor", '\u230A'); 754 entities.Add ("rfloor", '\u230B'); 755 entities.Add ("lang", '\u2329'); 756 entities.Add ("rang", '\u232A'); 757 entities.Add ("loz", '\u25CA'); 758 entities.Add ("spades", '\u2660'); 759 entities.Add ("clubs", '\u2663'); 760 entities.Add ("hearts", '\u2665'); 761 entities.Add ("diams", '\u2666'); 762 entities.Add ("quot", '\u0022'); 763 entities.Add ("amp", '\u0026'); 764 entities.Add ("lt", '\u003C'); 765 entities.Add ("gt", '\u003E'); 766 entities.Add ("OElig", '\u0152'); 767 entities.Add ("oelig", '\u0153'); 768 entities.Add ("Scaron", '\u0160'); 769 entities.Add ("scaron", '\u0161'); 770 entities.Add ("Yuml", '\u0178'); 771 entities.Add ("circ", '\u02C6'); 772 entities.Add ("tilde", '\u02DC'); 773 entities.Add ("ensp", '\u2002'); 774 entities.Add ("emsp", '\u2003'); 775 entities.Add ("thinsp", '\u2009'); 776 entities.Add ("zwnj", '\u200C'); 777 entities.Add ("zwj", '\u200D'); 778 entities.Add ("lrm", '\u200E'); 779 entities.Add ("rlm", '\u200F'); 780 entities.Add ("ndash", '\u2013'); 781 entities.Add ("mdash", '\u2014'); 782 entities.Add ("lsquo", '\u2018'); 783 entities.Add ("rsquo", '\u2019'); 784 entities.Add ("sbquo", '\u201A'); 785 entities.Add ("ldquo", '\u201C'); 786 entities.Add ("rdquo", '\u201D'); 787 entities.Add ("bdquo", '\u201E'); 788 entities.Add ("dagger", '\u2020'); 789 entities.Add ("Dagger", '\u2021'); 790 entities.Add ("permil", '\u2030'); 791 entities.Add ("lsaquo", '\u2039'); 792 entities.Add ("rsaquo", '\u203A'); 793 entities.Add ("euro", '\u20AC'); 794 } 795 } 796 } 797