Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
HttpEncoder.cs
Go to the documentation of this file.
3using System.IO;
4using System.Net;
5using System.Text;
6
8
9internal static class HttpEncoder
10{
11 private sealed class UrlDecoder
12 {
13 private readonly int _bufferSize;
14
15 private int _numChars;
16
17 private readonly char[] _charBuffer;
18
19 private int _numBytes;
20
21 private byte[] _byteBuffer;
22
23 private readonly Encoding _encoding;
24
25 private void FlushBytes()
26 {
27 if (_numBytes > 0)
28 {
30 _numBytes = 0;
31 }
32 }
33
34 internal UrlDecoder(int bufferSize, Encoding encoding)
35 {
36 _bufferSize = bufferSize;
37 _encoding = encoding;
38 _charBuffer = new char[bufferSize];
39 }
40
41 internal void AddChar(char ch)
42 {
43 if (_numBytes > 0)
44 {
45 FlushBytes();
46 }
48 }
49
50 internal void AddByte(byte b)
51 {
52 if (_byteBuffer == null)
53 {
54 _byteBuffer = new byte[_bufferSize];
55 }
57 }
58
59 internal string GetString()
60 {
61 if (_numBytes > 0)
62 {
63 FlushBytes();
64 }
65 if (_numChars <= 0)
66 {
67 return "";
68 }
69 return new string(_charBuffer, 0, _numChars);
70 }
71 }
72
73 private static void AppendCharAsUnicodeJavaScript(StringBuilder builder, char c)
74 {
76 handler.AppendLiteral("\\u");
77 handler.AppendFormatted((int)c, "x4");
78 builder.Append(ref handler);
79 }
80
81 private static bool CharRequiresJavaScriptEncoding(char c)
82 {
83 if (c >= ' ' && c != '"' && c != '\\' && c != '\'' && c != '<' && c != '>' && c != '&' && c != '\u0085' && c != '\u2028')
84 {
85 return c == '\u2029';
86 }
87 return true;
88 }
89
90 [return: NotNullIfNotNull("value")]
91 internal static string HtmlAttributeEncode(string value)
92 {
93 if (string.IsNullOrEmpty(value))
94 {
95 return value;
96 }
98 if (num == -1)
99 {
100 return value;
101 }
103 HtmlAttributeEncode(value, stringWriter);
104 return stringWriter.ToString();
105 }
106
107 internal static void HtmlAttributeEncode(string value, TextWriter output)
108 {
109 if (value != null)
110 {
111 if (output == null)
112 {
113 throw new ArgumentNullException("output");
114 }
116 }
117 }
118
119 private static void HtmlAttributeEncodeInternal(string s, TextWriter output)
120 {
122 if (num == -1)
123 {
124 output.Write(s);
125 return;
126 }
127 output.Write(s.AsSpan(0, num));
128 ReadOnlySpan<char> readOnlySpan = s.AsSpan(num);
129 for (int i = 0; i < readOnlySpan.Length; i++)
130 {
131 char c = readOnlySpan[i];
132 if (c <= '<')
133 {
134 switch (c)
135 {
136 case '<':
137 output.Write("&lt;");
138 break;
139 case '"':
140 output.Write("&quot;");
141 break;
142 case '\'':
143 output.Write("&#39;");
144 break;
145 case '&':
146 output.Write("&amp;");
147 break;
148 default:
149 output.Write(c);
150 break;
151 }
152 }
153 else
154 {
155 output.Write(c);
156 }
157 }
158 }
159
160 [return: NotNullIfNotNull("value")]
161 internal static string HtmlDecode(string value)
162 {
163 if (!string.IsNullOrEmpty(value))
164 {
166 }
167 return value;
168 }
169
170 internal static void HtmlDecode(string value, TextWriter output)
171 {
172 if (output == null)
173 {
174 throw new ArgumentNullException("output");
175 }
177 }
178
179 [return: NotNullIfNotNull("value")]
180 internal static string HtmlEncode(string value)
181 {
182 if (!string.IsNullOrEmpty(value))
183 {
185 }
186 return value;
187 }
188
189 internal static void HtmlEncode(string value, TextWriter output)
190 {
191 if (output == null)
192 {
193 throw new ArgumentNullException("output");
194 }
196 }
197
198 private static int IndexOfHtmlAttributeEncodingChars(string s, int startPos)
199 {
200 ReadOnlySpan<char> readOnlySpan = s.AsSpan(startPos);
201 for (int i = 0; i < readOnlySpan.Length; i++)
202 {
203 switch (readOnlySpan[i])
204 {
205 case '"':
206 case '&':
207 case '\'':
208 case '<':
209 return startPos + i;
210 }
211 }
212 return -1;
213 }
214
215 private static bool IsNonAsciiByte(byte b)
216 {
217 if (b < 127)
218 {
219 return b < 32;
220 }
221 return true;
222 }
223
224 internal static string JavaScriptStringEncode(string value)
225 {
226 if (string.IsNullOrEmpty(value))
227 {
228 return string.Empty;
229 }
230 StringBuilder stringBuilder = null;
231 int startIndex = 0;
232 int num = 0;
233 for (int i = 0; i < value.Length; i++)
234 {
235 char c = value[i];
237 {
238 if (stringBuilder == null)
239 {
240 stringBuilder = new StringBuilder(value.Length + 5);
241 }
242 if (num > 0)
243 {
244 stringBuilder.Append(value, startIndex, num);
245 }
246 startIndex = i + 1;
247 num = 0;
248 switch (c)
249 {
250 case '\r':
251 stringBuilder.Append("\\r");
252 break;
253 case '\t':
254 stringBuilder.Append("\\t");
255 break;
256 case '"':
257 stringBuilder.Append("\\\"");
258 break;
259 case '\\':
260 stringBuilder.Append("\\\\");
261 break;
262 case '\n':
263 stringBuilder.Append("\\n");
264 break;
265 case '\b':
266 stringBuilder.Append("\\b");
267 break;
268 case '\f':
269 stringBuilder.Append("\\f");
270 break;
271 default:
272 AppendCharAsUnicodeJavaScript(stringBuilder, c);
273 break;
274 }
275 }
276 else
277 {
278 num++;
279 }
280 }
281 if (stringBuilder == null)
282 {
283 return value;
284 }
285 if (num > 0)
286 {
287 stringBuilder.Append(value, startIndex, num);
288 }
289 return stringBuilder.ToString();
290 }
291
292 [return: NotNullIfNotNull("bytes")]
293 internal static byte[] UrlDecode(byte[] bytes, int offset, int count)
294 {
296 {
297 return null;
298 }
299 int num = 0;
300 byte[] array = new byte[count];
301 for (int i = 0; i < count; i++)
302 {
303 int num2 = offset + i;
304 byte b = bytes[num2];
305 switch (b)
306 {
307 case 43:
308 b = 32;
309 break;
310 case 37:
311 if (i < count - 2)
312 {
313 int num3 = System.HexConverter.FromChar(bytes[num2 + 1]);
314 int num4 = System.HexConverter.FromChar(bytes[num2 + 2]);
315 if ((num3 | num4) != 255)
316 {
317 b = (byte)((num3 << 4) | num4);
318 i += 2;
319 }
320 }
321 break;
322 }
323 array[num++] = b;
324 }
325 if (num < array.Length)
326 {
327 byte[] array2 = new byte[num];
328 Array.Copy(array, array2, num);
329 array = array2;
330 }
331 return array;
332 }
333
334 [return: NotNullIfNotNull("bytes")]
335 internal static string UrlDecode(byte[] bytes, int offset, int count, Encoding encoding)
336 {
338 {
339 return null;
340 }
341 UrlDecoder urlDecoder = new UrlDecoder(count, encoding);
342 for (int i = 0; i < count; i++)
343 {
344 int num = offset + i;
345 byte b = bytes[num];
346 switch (b)
347 {
348 case 43:
349 b = 32;
350 break;
351 case 37:
352 if (i >= count - 2)
353 {
354 break;
355 }
356 if (bytes[num + 1] == 117 && i < count - 5)
357 {
358 int num2 = System.HexConverter.FromChar(bytes[num + 2]);
359 int num3 = System.HexConverter.FromChar(bytes[num + 3]);
360 int num4 = System.HexConverter.FromChar(bytes[num + 4]);
361 int num5 = System.HexConverter.FromChar(bytes[num + 5]);
362 if ((num2 | num3 | num4 | num5) != 255)
363 {
364 char ch = (char)((num2 << 12) | (num3 << 8) | (num4 << 4) | num5);
365 i += 5;
366 urlDecoder.AddChar(ch);
367 continue;
368 }
369 }
370 else
371 {
372 int num6 = System.HexConverter.FromChar(bytes[num + 1]);
373 int num7 = System.HexConverter.FromChar(bytes[num + 2]);
374 if ((num6 | num7) != 255)
375 {
376 b = (byte)((num6 << 4) | num7);
377 i += 2;
378 }
379 }
380 break;
381 }
382 urlDecoder.AddByte(b);
383 }
384 return Utf16StringValidator.ValidateString(urlDecoder.GetString());
385 }
386
387 [return: NotNullIfNotNull("value")]
388 internal static string UrlDecode(string value, Encoding encoding)
389 {
390 if (value == null)
391 {
392 return null;
393 }
394 int length = value.Length;
395 UrlDecoder urlDecoder = new UrlDecoder(length, encoding);
396 for (int i = 0; i < length; i++)
397 {
398 char c = value[i];
399 switch (c)
400 {
401 case '+':
402 c = ' ';
403 break;
404 case '%':
405 if (i >= length - 2)
406 {
407 break;
408 }
409 if (value[i + 1] == 'u' && i < length - 5)
410 {
411 int num = System.HexConverter.FromChar(value[i + 2]);
412 int num2 = System.HexConverter.FromChar(value[i + 3]);
413 int num3 = System.HexConverter.FromChar(value[i + 4]);
414 int num4 = System.HexConverter.FromChar(value[i + 5]);
415 if ((num | num2 | num3 | num4) != 255)
416 {
417 c = (char)((num << 12) | (num2 << 8) | (num3 << 4) | num4);
418 i += 5;
419 urlDecoder.AddChar(c);
420 continue;
421 }
422 }
423 else
424 {
425 int num5 = System.HexConverter.FromChar(value[i + 1]);
426 int num6 = System.HexConverter.FromChar(value[i + 2]);
427 if ((num5 | num6) != 255)
428 {
429 byte b = (byte)((num5 << 4) | num6);
430 i += 2;
431 urlDecoder.AddByte(b);
432 continue;
433 }
434 }
435 break;
436 }
437 if ((c & 0xFF80) == 0)
438 {
439 urlDecoder.AddByte((byte)c);
440 }
441 else
442 {
443 urlDecoder.AddChar(c);
444 }
445 }
446 return Utf16StringValidator.ValidateString(urlDecoder.GetString());
447 }
448
449 [return: NotNullIfNotNull("bytes")]
450 internal static byte[] UrlEncode(byte[] bytes, int offset, int count, bool alwaysCreateNewReturnValue)
451 {
452 byte[] array = UrlEncode(bytes, offset, count);
453 if (!alwaysCreateNewReturnValue || array == null || array != bytes)
454 {
455 return array;
456 }
457 return (byte[])array.Clone();
458 }
459
460 [return: NotNullIfNotNull("bytes")]
461 private static byte[] UrlEncode(byte[] bytes, int offset, int count)
462 {
464 {
465 return null;
466 }
467 int num = 0;
468 int num2 = 0;
469 for (int i = 0; i < count; i++)
470 {
471 char c = (char)bytes[offset + i];
472 if (c == ' ')
473 {
474 num++;
475 }
477 {
478 num2++;
479 }
480 }
481 if (num == 0 && num2 == 0)
482 {
483 if (offset == 0 && bytes.Length == count)
484 {
485 return bytes;
486 }
487 byte[] array = new byte[count];
489 return array;
490 }
491 byte[] array2 = new byte[count + num2 * 2];
492 int num3 = 0;
493 for (int j = 0; j < count; j++)
494 {
495 byte b = bytes[offset + j];
496 char c2 = (char)b;
498 {
499 array2[num3++] = b;
500 continue;
501 }
502 if (c2 == ' ')
503 {
504 array2[num3++] = 43;
505 continue;
506 }
507 array2[num3++] = 37;
508 array2[num3++] = (byte)System.HexConverter.ToCharLower(b >> 4);
509 array2[num3++] = (byte)System.HexConverter.ToCharLower(b);
510 }
511 return array2;
512 }
513
514 private static string UrlEncodeNonAscii(string str, Encoding e)
515 {
516 byte[] bytes = e.GetBytes(str);
517 byte[] bytes2 = UrlEncodeNonAscii(bytes, 0, bytes.Length);
518 return Encoding.ASCII.GetString(bytes2);
519 }
520
521 private static byte[] UrlEncodeNonAscii(byte[] bytes, int offset, int count)
522 {
523 int num = 0;
524 for (int i = 0; i < count; i++)
525 {
526 if (IsNonAsciiByte(bytes[offset + i]))
527 {
528 num++;
529 }
530 }
531 if (num == 0)
532 {
533 return bytes;
534 }
535 byte[] array = new byte[count + num * 2];
536 int num2 = 0;
537 for (int j = 0; j < count; j++)
538 {
539 byte b = bytes[offset + j];
540 if (IsNonAsciiByte(b))
541 {
542 array[num2++] = 37;
543 array[num2++] = (byte)System.HexConverter.ToCharLower(b >> 4);
544 array[num2++] = (byte)System.HexConverter.ToCharLower(b);
545 }
546 else
547 {
548 array[num2++] = b;
549 }
550 }
551 return array;
552 }
553
554 [Obsolete("This method produces non-standards-compliant output and has interoperability issues. The preferred alternative is UrlEncode(*).")]
555 [return: NotNullIfNotNull("value")]
556 internal static string UrlEncodeUnicode(string value)
557 {
558 if (value == null)
559 {
560 return null;
561 }
562 int length = value.Length;
563 StringBuilder stringBuilder = new StringBuilder(length);
564 for (int i = 0; i < length; i++)
565 {
566 char c = value[i];
567 if ((c & 0xFF80) == 0)
568 {
570 {
571 stringBuilder.Append(c);
572 continue;
573 }
574 if (c == ' ')
575 {
576 stringBuilder.Append('+');
577 continue;
578 }
579 stringBuilder.Append('%');
580 stringBuilder.Append(System.HexConverter.ToCharLower((int)c >> 4));
581 stringBuilder.Append(System.HexConverter.ToCharLower(c));
582 }
583 else
584 {
585 stringBuilder.Append("%u");
586 stringBuilder.Append(System.HexConverter.ToCharLower((int)c >> 12));
587 stringBuilder.Append(System.HexConverter.ToCharLower((int)c >> 8));
588 stringBuilder.Append(System.HexConverter.ToCharLower((int)c >> 4));
589 stringBuilder.Append(System.HexConverter.ToCharLower(c));
590 }
591 }
592 return stringBuilder.ToString();
593 }
594
595 [return: NotNullIfNotNull("value")]
596 internal static string UrlPathEncode(string value)
597 {
598 if (string.IsNullOrEmpty(value))
599 {
600 return value;
601 }
602 if (!UriUtil.TrySplitUriForPathEncode(value, out var schemeAndAuthority, out var path, out var queryAndFragment))
603 {
604 schemeAndAuthority = null;
605 path = value;
606 queryAndFragment = null;
607 }
608 return schemeAndAuthority + UrlPathEncodeImpl(path) + queryAndFragment;
609 }
610
611 private static string UrlPathEncodeImpl(string value)
612 {
613 if (string.IsNullOrEmpty(value))
614 {
615 return value;
616 }
617 int num = value.IndexOf('?');
618 if (num >= 0)
619 {
620 return UrlPathEncodeImpl(value.Substring(0, num)) + value.AsSpan(num);
621 }
623 }
624
625 private static bool ValidateUrlEncodingParameters([NotNullWhen(true)] byte[] bytes, int offset, int count)
626 {
627 if (bytes == null && count == 0)
628 {
629 return false;
630 }
631 if (bytes == null)
632 {
633 throw new ArgumentNullException("bytes");
634 }
635 if (offset < 0 || offset > bytes.Length)
636 {
637 throw new ArgumentOutOfRangeException("offset");
638 }
639 if (count < 0 || offset + count > bytes.Length)
640 {
641 throw new ArgumentOutOfRangeException("count");
642 }
643 return true;
644 }
645}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static CultureInfo InvariantCulture
static char ToCharLower(int value)
static int FromChar(int c)
override string ToString()
virtual void Write(char value)
static ? string HtmlDecode(string? value)
static ? string HtmlEncode(string? value)
static Encoding UTF8
Definition Encoding.cs:526
static Encoding ASCII
Definition Encoding.cs:511
virtual byte[] GetBytes(char[] chars)
Definition Encoding.cs:781
virtual char[] GetChars(byte[] bytes)
Definition Encoding.cs:921
override string ToString()
StringBuilder Append(char value, int repeatCount)
static string UrlEncodeSpaces(string str)
UrlDecoder(int bufferSize, Encoding encoding)
static string UrlEncodeNonAscii(string str, Encoding e)
static byte[] UrlEncode(byte[] bytes, int offset, int count, bool alwaysCreateNewReturnValue)
static string UrlDecode(string value, Encoding encoding)
static bool IsNonAsciiByte(byte b)
static void HtmlEncode(string value, TextWriter output)
static string HtmlDecode(string value)
static string UrlEncodeUnicode(string value)
static bool CharRequiresJavaScriptEncoding(char c)
static bool ValidateUrlEncodingParameters([NotNullWhen(true)] byte[] bytes, int offset, int count)
static byte[] UrlEncode(byte[] bytes, int offset, int count)
static string JavaScriptStringEncode(string value)
static void HtmlAttributeEncodeInternal(string s, TextWriter output)
static void HtmlAttributeEncode(string value, TextWriter output)
static string HtmlEncode(string value)
static string UrlPathEncodeImpl(string value)
static byte[] UrlEncodeNonAscii(byte[] bytes, int offset, int count)
static string UrlDecode(byte[] bytes, int offset, int count, Encoding encoding)
static void AppendCharAsUnicodeJavaScript(StringBuilder builder, char c)
static void HtmlDecode(string value, TextWriter output)
static string UrlPathEncode(string value)
static string HtmlAttributeEncode(string value)
static int IndexOfHtmlAttributeEncodingChars(string s, int startPos)
static byte[] UrlDecode(byte[] bytes, int offset, int count)
static bool TrySplitUriForPathEncode(string input, [NotNullWhen(true)] out string schemeAndAuthority, [NotNullWhen(true)] out string path, out string queryAndFragment)
Definition UriUtil.cs:24
static string ValidateString(string input)