public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters, bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, IArrayPool<char> bufferPool, ref char[] writeBuffer) { // leading delimiter if (appendDelimiters) { writer.Write(delimiter); } if (s != null) { int lastWritePosition = 0; for (int i = 0; i < s.Length; i++) { var c = s[i]; if (c < charEscapeFlags.Length && !charEscapeFlags[c]) { continue; } string escapedValue; switch (c) { case '\t': escapedValue = @"\t"; break; case '\n': escapedValue = @"\n"; break; case '\r': escapedValue = @"\r"; break; case '\f': escapedValue = @"\f"; break; case '\b': escapedValue = @"\b"; break; case '\\': escapedValue = @"\\"; break; case '\u0085': // Next Line escapedValue = @"\u0085"; break; case '\u2028': // Line Separator escapedValue = @"\u2028"; break; case '\u2029': // Paragraph Separator escapedValue = @"\u2029"; break; default: if (c < charEscapeFlags.Length || stringEscapeHandling == StringEscapeHandling.EscapeNonAscii) { if (c == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) { escapedValue = @"\'"; } else if (c == '"' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) { escapedValue = @"\"""; } else { if (writeBuffer == null || writeBuffer.Length < UnicodeTextLength) { writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, UnicodeTextLength, writeBuffer); } StringUtils.ToCharAsUnicode(c, writeBuffer); // slightly hacky but it saves multiple conditions in if test escapedValue = EscapedUnicodeText; } } else { escapedValue = null; } break; } if (escapedValue == null) { continue; } bool isEscapedUnicodeText = string.Equals(escapedValue, EscapedUnicodeText); if (i > lastWritePosition) { int length = i - lastWritePosition + ((isEscapedUnicodeText) ? UnicodeTextLength : 0); int start = (isEscapedUnicodeText) ? UnicodeTextLength : 0; if (writeBuffer == null || writeBuffer.Length < length) { char[] newBuffer = BufferUtils.RentBuffer(bufferPool, length); // the unicode text is already in the buffer // copy it over when creating new buffer if (isEscapedUnicodeText) { Array.Copy(writeBuffer, newBuffer, UnicodeTextLength); } BufferUtils.ReturnBuffer(bufferPool, writeBuffer); writeBuffer = newBuffer; } s.CopyTo(lastWritePosition, writeBuffer, start, length - start); // write unchanged chars before writing escaped text writer.Write(writeBuffer, start, length - start); } lastWritePosition = i + 1; if (!isEscapedUnicodeText) { writer.Write(escapedValue); } else { writer.Write(writeBuffer, 0, UnicodeTextLength); } } if (lastWritePosition == 0) { // no escaped text, write entire string writer.Write(s); } else { int length = s.Length - lastWritePosition; if (writeBuffer == null || writeBuffer.Length < length) { writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, length, writeBuffer); } s.CopyTo(lastWritePosition, writeBuffer, 0, length); // write remaining text writer.Write(writeBuffer, 0, length); } } // trailing delimiter if (appendDelimiters) { writer.Write(delimiter); } }
private static async Task WriteDefinitelyEscapedJavaScriptStringWithoutDelimitersAsync(TextWriter writer, string s, int lastWritePosition, bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken) { int length; ConfiguredTaskAwaitable configuredTaskAwaitable; char chr; if (writeBuffer == null || (int)writeBuffer.Length < lastWritePosition) { writeBuffer = client.EnsureWriteBuffer(lastWritePosition, 6); } if (lastWritePosition != 0) { s.CopyTo(0, writeBuffer, 0, lastWritePosition); configuredTaskAwaitable = writer.WriteAsync(writeBuffer, 0, lastWritePosition, cancellationToken).ConfigureAwait(false); await configuredTaskAwaitable; } bool flag = false; string str = null; for (int i = lastWritePosition; i < s.Length; i++) { chr = s[i]; if (chr >= (char)((int)charEscapeFlags.Length) || charEscapeFlags[chr]) { if (chr <= '\\') { switch (chr) { case '\b': { str = "\\b"; break; } case '\t': { str = "\\t"; break; } case '\n': { str = "\\n"; break; } case '\v': { goto Label0; } case '\f': { str = "\\f"; break; } case '\r': { str = "\\r"; break; } default: { if (chr == '\\') { str = "\\\\"; break; } else { goto Label0; } } } } else if (chr == '\u0085') { str = "\\u0085"; } else if (chr == '\u2028') { str = "\\u2028"; } else { if (chr != '\u2029') { goto Label0; } str = "\\u2029"; } Label2: if (i > lastWritePosition) { int num = i - lastWritePosition; length = num + (flag ? 6 : 0); int num1 = (flag ? 6 : 0); if ((int)writeBuffer.Length < length) { writeBuffer = client.EnsureWriteBuffer(length, 6); } s.CopyTo(lastWritePosition, writeBuffer, num1, length - num1); configuredTaskAwaitable = writer.WriteAsync(writeBuffer, num1, length - num1, cancellationToken).ConfigureAwait(false); await configuredTaskAwaitable; } lastWritePosition = i + 1; if (flag) { configuredTaskAwaitable = writer.WriteAsync(writeBuffer, 0, 6, cancellationToken).ConfigureAwait(false); await configuredTaskAwaitable; flag = false; } else { configuredTaskAwaitable = writer.WriteAsync(str, cancellationToken).ConfigureAwait(false); await configuredTaskAwaitable; } } Label1: } length = s.Length - lastWritePosition; if (length != 0) { if ((int)writeBuffer.Length < length) { writeBuffer = client.EnsureWriteBuffer(length, 0); } s.CopyTo(lastWritePosition, writeBuffer, 0, length); configuredTaskAwaitable = writer.WriteAsync(writeBuffer, 0, length, cancellationToken).ConfigureAwait(false); await configuredTaskAwaitable; } return; Label0: if (chr >= (char)((int)charEscapeFlags.Length) && stringEscapeHandling != StringEscapeHandling.EscapeNonAscii) { goto Label1; } if (chr == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) { str = "\\'"; goto Label2; } else if (chr != '\"' || stringEscapeHandling == StringEscapeHandling.EscapeHtml) { if ((int)writeBuffer.Length < 6) { writeBuffer = client.EnsureWriteBuffer(6, 0); } StringUtils.ToCharAsUnicode(chr, writeBuffer); flag = true; goto Label2; } else { str = "\\\""; goto Label2; } }
public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters, bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, IArrayPool <char> bufferPool, ref char[] writeBuffer) { int length; char chr; string str; if (appendDelimiters) { writer.Write(delimiter); } if (!string.IsNullOrEmpty(s)) { int escape = JavaScriptUtils.FirstCharToEscape(s, charEscapeFlags, stringEscapeHandling); if (escape != -1) { if (escape != 0) { if (writeBuffer == null || (int)writeBuffer.Length < escape) { writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, escape, writeBuffer); } s.CopyTo(0, writeBuffer, 0, escape); writer.Write(writeBuffer, 0, escape); } for (int i = escape; i < s.Length; i++) { chr = s[i]; if (chr >= (char)((int)charEscapeFlags.Length) || charEscapeFlags[chr]) { if (chr <= '\\') { switch (chr) { case '\b': { str = "\\b"; break; } case '\t': { str = "\\t"; break; } case '\n': { str = "\\n"; break; } case '\v': { goto Label0; } case '\f': { str = "\\f"; break; } case '\r': { str = "\\r"; break; } default: { if (chr == '\\') { str = "\\\\"; break; } else { goto Label0; } } } } else if (chr == '\u0085') { str = "\\u0085"; } else if (chr == '\u2028') { str = "\\u2028"; } else { if (chr != '\u2029') { goto Label0; } str = "\\u2029"; } Label1: if (str != null) { bool flag = string.Equals(str, "!"); if (i > escape) { length = i - escape + (flag ? 6 : 0); int num = (flag ? 6 : 0); if (writeBuffer == null || (int)writeBuffer.Length < length) { char[] chrArray = BufferUtils.RentBuffer(bufferPool, length); if (flag) { Array.Copy(writeBuffer, chrArray, 6); } BufferUtils.ReturnBuffer(bufferPool, writeBuffer); writeBuffer = chrArray; } s.CopyTo(escape, writeBuffer, num, length - num); writer.Write(writeBuffer, num, length - num); } escape = i + 1; if (flag) { writer.Write(writeBuffer, 0, 6); } else { writer.Write(str); } } } } length = s.Length - escape; if (length > 0) { if (writeBuffer == null || (int)writeBuffer.Length < length) { writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, length, writeBuffer); } s.CopyTo(escape, writeBuffer, 0, length); writer.Write(writeBuffer, 0, length); } } else { writer.Write(s); } } if (appendDelimiters) { writer.Write(delimiter); } return; Label0: if (chr >= (char)((int)charEscapeFlags.Length)) { if (stringEscapeHandling == StringEscapeHandling.EscapeNonAscii) { goto Label3; } str = null; goto Label1; } if (chr == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) { str = "\\'"; goto Label1; } else if (chr != '\"' || stringEscapeHandling == StringEscapeHandling.EscapeHtml) { if (writeBuffer == null || (int)writeBuffer.Length < 6) { writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, 6, writeBuffer); } StringUtils.ToCharAsUnicode(chr, writeBuffer); str = "!"; goto Label1; } else { str = "\\\""; goto Label1; } }
public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters) { // leading delimiter if (appendDelimiters) { writer.Write(delimiter); } if (s != null) { char[] chars = null; int lastWritePosition = 0; for (int i = 0; i < s.Length; i++) { var c = s[i]; // don't escape standard text/numbers except '\' and the text delimiter if (c >= ' ' && c < 128 && c != '\\' && c != delimiter) { continue; } string escapedValue; switch (c) { case '\t': escapedValue = @"\t"; break; case '\n': escapedValue = @"\n"; break; case '\r': escapedValue = @"\r"; break; case '\f': escapedValue = @"\f"; break; case '\b': escapedValue = @"\b"; break; case '\\': escapedValue = @"\\"; break; case '\u0085': // Next Line escapedValue = @"\u0085"; break; case '\u2028': // Line Separator escapedValue = @"\u2028"; break; case '\u2029': // Paragraph Separator escapedValue = @"\u2029"; break; case '\'': // this charater is being used as the delimiter escapedValue = @"\'"; break; case '"': // this charater is being used as the delimiter escapedValue = "\\\""; break; default: escapedValue = (c <= '\u001f') ? StringUtils.ToCharAsUnicode(c) : null; break; } if (escapedValue == null) { continue; } if (i > lastWritePosition) { if (chars == null) { chars = s.ToCharArray(); } // write unchanged chars before writing escaped text writer.Write(chars, lastWritePosition, i - lastWritePosition); } lastWritePosition = i + 1; writer.Write(escapedValue); } if (lastWritePosition == 0) { // no escaped text, write entire string writer.Write(s); } else { if (chars == null) { chars = s.ToCharArray(); } // write remaining text writer.Write(chars, lastWritePosition, s.Length - lastWritePosition); } } // trailing delimiter if (appendDelimiters) { writer.Write(delimiter); } }