<PackageReference Include="System.Text.Encodings.Web" Version="5.0.0-rc.2.20475.5" />

DefaultJavaScriptEncoder

using System.Runtime.CompilerServices; using System.Text.Internal; using System.Text.Unicode; namespace System.Text.Encodings.Web { internal sealed class DefaultJavaScriptEncoder : JavaScriptEncoder { private readonly AllowedCharactersBitmap _allowedCharacters; private readonly int[] _asciiNeedsEscaping = new int[128]; private static readonly char[] s_b = new char[2] { '\\', 'b' }; private static readonly char[] s_t = new char[2] { '\\', 't' }; private static readonly char[] s_n = new char[2] { '\\', 'n' }; private static readonly char[] s_f = new char[2] { '\\', 'f' }; private static readonly char[] s_r = new char[2] { '\\', 'r' }; private static readonly char[] s_back = new char[2] { '\\', '\\' }; public override int MaxOutputCharactersPerInputCharacter => 12; public DefaultJavaScriptEncoder(TextEncoderSettings filter) { if (filter == null) throw new ArgumentNullException("filter"); _allowedCharacters = filter.GetAllowedCharacters(); _allowedCharacters.ForbidUndefinedCharacters(); DefaultHtmlEncoder.ForbidHtmlCharacters(_allowedCharacters); _allowedCharacters.ForbidCharacter('\\'); _allowedCharacters.ForbidCharacter('`'); for (int i = 0; i < _asciiNeedsEscaping.Length; i++) { _asciiNeedsEscaping[i] = (WillEncode(i) ? 1 : (-1)); } } public DefaultJavaScriptEncoder(params UnicodeRange[] allowedRanges) : this(new TextEncoderSettings(allowedRanges)) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool WillEncode(int unicodeScalar) { if (UnicodeHelpers.IsSupplementaryCodePoint(unicodeScalar)) return true; return !_allowedCharacters.IsUnicodeScalarAllowed(unicodeScalar); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe override int FindFirstCharacterToEncode(char* text, int textLength) { if (text == null) throw new ArgumentNullException("text"); return _allowedCharacters.FindFirstCharacterToEncode(text, textLength); } public unsafe override int FindFirstCharacterToEncodeUtf8(ReadOnlySpan<byte> utf8Text) { fixed (byte* ptr = &utf8Text.GetPinnableReference()) { int num = 0; while (true) { if (num >= utf8Text.Length) { num = -1; break; } if (System.Text.UnicodeUtility.IsAsciiCodePoint(ptr[num])) { if (DoesAsciiNeedEncoding(ptr[num]) == 1) break; num++; } else { if (UnicodeHelpers.DecodeScalarValueFromUtf8(utf8Text.Slice(num), out uint result, out int bytesConsumed) != 0 || WillEncode((int)result)) break; num += bytesConsumed; } } return num; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private int DoesAsciiNeedEncoding(byte value) { return _asciiNeedsEscaping[value]; } public unsafe override bool TryEncodeUnicodeScalar(int unicodeScalar, char* buffer, int bufferLength, out int numberOfCharactersWritten) { if (buffer == null) throw new ArgumentNullException("buffer"); if (!WillEncode(unicodeScalar)) return TextEncoder.TryWriteScalarAsChar(unicodeScalar, buffer, bufferLength, out numberOfCharactersWritten); char[] source; switch (unicodeScalar) { case 8: source = s_b; break; case 9: source = s_t; break; case 10: source = s_n; break; case 12: source = s_f; break; case 13: source = s_r; break; case 92: source = s_back; break; default: return JavaScriptEncoderHelper.TryWriteEncodedScalarAsNumericEntity(unicodeScalar, buffer, bufferLength, out numberOfCharactersWritten); } return TextEncoder.TryCopyCharacters(source, buffer, bufferLength, out numberOfCharactersWritten); } } }