in src/Elastic.Apm/Libraries/Newtonsoft.Json/Utilities/JavaScriptUtils.cs [377:509]
private static async Task WriteDefinitelyEscapedJavaScriptStringWithoutDelimitersAsync(
TextWriter writer, string s, int lastWritePosition, bool[] charEscapeFlags,
StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer,
CancellationToken cancellationToken)
{
if (writeBuffer == null || writeBuffer.Length < lastWritePosition)
{
writeBuffer = client.EnsureWriteBuffer(lastWritePosition, UnicodeTextLength);
}
if (lastWritePosition != 0)
{
s.CopyTo(0, writeBuffer, 0, lastWritePosition);
// write unchanged chars at start of text.
await writer.WriteAsync(writeBuffer, 0, lastWritePosition, cancellationToken).ConfigureAwait(false);
}
int length;
bool isEscapedUnicodeText = false;
string? escapedValue = null;
for (int i = lastWritePosition; i < s.Length; i++)
{
char c = s[i];
if (c < charEscapeFlags.Length && !charEscapeFlags[c])
{
continue;
}
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.Length < UnicodeTextLength)
{
writeBuffer = client.EnsureWriteBuffer(UnicodeTextLength, 0);
}
StringUtils.ToCharAsUnicode(c, writeBuffer);
isEscapedUnicodeText = true;
}
}
else
{
continue;
}
break;
}
if (i > lastWritePosition)
{
length = i - lastWritePosition + (isEscapedUnicodeText ? UnicodeTextLength : 0);
int start = isEscapedUnicodeText ? UnicodeTextLength : 0;
if (writeBuffer.Length < length)
{
writeBuffer = client.EnsureWriteBuffer(length, UnicodeTextLength);
}
s.CopyTo(lastWritePosition, writeBuffer, start, length - start);
// write unchanged chars before writing escaped text
await writer.WriteAsync(writeBuffer, start, length - start, cancellationToken).ConfigureAwait(false);
}
lastWritePosition = i + 1;
if (!isEscapedUnicodeText)
{
await writer.WriteAsync(escapedValue!, cancellationToken).ConfigureAwait(false);
}
else
{
await writer.WriteAsync(writeBuffer, 0, UnicodeTextLength, cancellationToken).ConfigureAwait(false);
isEscapedUnicodeText = false;
}
}
length = s.Length - lastWritePosition;
if (length != 0)
{
if (writeBuffer.Length < length)
{
writeBuffer = client.EnsureWriteBuffer(length, 0);
}
s.CopyTo(lastWritePosition, writeBuffer, 0, length);
// write remaining text
await writer.WriteAsync(writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
}
}