HttpEncode.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using System.Text;
  2. using static System.String;
  3. namespace Abp.Web.Http
  4. {
  5. public static class HttpEncode
  6. {
  7. public static bool JavaScriptEncodeAmpersand { get; set; }
  8. private static bool CharRequiresJavaScriptEncoding(char c)
  9. {
  10. return c < 0x20 // control chars always have to be encoded
  11. || c == '\"' // chars which must be encoded per JSON spec
  12. || c == '\\'
  13. || c == '\'' // HTML-sensitive chars encoded for safety
  14. || c == '<'
  15. || c == '>'
  16. || (c == '&' && JavaScriptEncodeAmpersand) // Bug Dev11 #133237. Encode '&' to provide additional security for people who incorrectly call the encoding methods (unless turned off by backcompat switch)
  17. || c == '\u0085' // newline chars (see Unicode 6.2, Table 5-1 [http://www.unicode.org/versions/Unicode6.2.0/ch05.pdf]) have to be encoded (DevDiv #663531)
  18. || c == '\u2028'
  19. || c == '\u2029';
  20. }
  21. private static void AppendCharAsUnicodeJavaScript(StringBuilder builder, char c)
  22. {
  23. builder.Append("\\u");
  24. builder.Append(((int)c).ToString("x4"));
  25. }
  26. public static string JavaScriptStringEncode(string value)
  27. {
  28. if (IsNullOrEmpty(value))
  29. {
  30. return Empty;
  31. }
  32. StringBuilder builder = null;
  33. var startIndex = 0;
  34. var count = 0;
  35. for (var i = 0; i < value.Length; i++)
  36. {
  37. var c = value[i];
  38. if (CharRequiresJavaScriptEncoding(c))
  39. {
  40. if (builder == null)
  41. {
  42. builder = new StringBuilder(value.Length + 5);
  43. }
  44. if (count > 0)
  45. {
  46. builder.Append(value, startIndex, count);
  47. }
  48. startIndex = i + 1;
  49. count = 0;
  50. }
  51. switch (c)
  52. {
  53. case '\r':
  54. builder.Append("\\r");
  55. break;
  56. case '\t':
  57. builder.Append("\\t");
  58. break;
  59. case '\"':
  60. builder.Append("\\\"");
  61. break;
  62. case '\\':
  63. builder.Append("\\\\");
  64. break;
  65. case '\n':
  66. builder.Append("\\n");
  67. break;
  68. case '\b':
  69. builder.Append("\\b");
  70. break;
  71. case '\f':
  72. builder.Append("\\f");
  73. break;
  74. default:
  75. if (CharRequiresJavaScriptEncoding(c))
  76. {
  77. AppendCharAsUnicodeJavaScript(builder, c);
  78. }
  79. else
  80. {
  81. count++;
  82. }
  83. break;
  84. }
  85. }
  86. if (builder == null)
  87. {
  88. return value;
  89. }
  90. if (count > 0)
  91. {
  92. builder.Append(value, startIndex, count);
  93. }
  94. return builder.ToString();
  95. }
  96. }
  97. }