Do not over-escape writing Base64 strings within JSON using the writer. (dotnet/coref...
authorAhson Khan <ahson_ahmedk@yahoo.com>
Tue, 16 Jul 2019 18:56:21 +0000 (11:56 -0700)
committerGitHub <noreply@github.com>
Tue, 16 Jul 2019 18:56:21 +0000 (11:56 -0700)
Commit migrated from https://github.com/dotnet/corefx/commit/063e38c7bc66e076fdcc7521e4c69650baae9427

src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs
src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs
src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs
src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs

index 369d2b4..8304baa 100644 (file)
@@ -212,11 +212,11 @@ namespace System.Text.Json
         {
             int encodedLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length);
 
-            Debug.Assert(escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding < int.MaxValue - (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) - 6);
+            Debug.Assert(escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding < int.MaxValue - encodedLength - 6);
 
             // All ASCII, 2 quotes for property name, 2 quotes to surround the base-64 encoded string value, and 1 colon => escapedPropertyName.Length + encodedLength + 5
-            // Optionally, 1 list separator, and up to 3x growth when transcoding, with escaping which can by up to 6x.
-            int maxRequired = (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) + 6;
+            // Optionally, 1 list separator, and up to 3x growth when transcoding.
+            int maxRequired = (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + encodedLength + 6;
 
             if (_memory.Length - BytesPending < maxRequired)
             {
@@ -247,11 +247,11 @@ namespace System.Text.Json
         {
             int encodedLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length);
 
-            Debug.Assert(escapedPropertyName.Length < int.MaxValue - (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) - 6);
+            Debug.Assert(escapedPropertyName.Length < int.MaxValue - encodedLength - 6);
 
             // 2 quotes for property name, 2 quotes to surround the base-64 encoded string value, and 1 colon => escapedPropertyName.Length + encodedLength + 5
-            // Optionally, 1 list separator, with escaping which can by up to 6x.
-            int maxRequired = escapedPropertyName.Length + (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) + 6;
+            // Optionally, 1 list separator.
+            int maxRequired = escapedPropertyName.Length + encodedLength + 6;
 
             if (_memory.Length - BytesPending < maxRequired)
             {
@@ -286,11 +286,11 @@ namespace System.Text.Json
 
             int encodedLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length);
 
-            Debug.Assert(escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding < int.MaxValue - indent - (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) - 7 - s_newLineLength);
+            Debug.Assert(escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding < int.MaxValue - indent - encodedLength - 7 - s_newLineLength);
 
             // All ASCII, 2 quotes for property name, 2 quotes to surround the base-64 encoded string value, 1 colon, and 1 space => indent + escapedPropertyName.Length + encodedLength + 6
-            // Optionally, 1 list separator, 1-2 bytes for new line, and up to 3x growth when transcoding, with escaping which can by up to 6x.
-            int maxRequired = indent + (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) + 7 + s_newLineLength;
+            // Optionally, 1 list separator, 1-2 bytes for new line, and up to 3x growth when transcoding.
+            int maxRequired = indent + (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + encodedLength + 7 + s_newLineLength;
 
             if (_memory.Length - BytesPending < maxRequired)
             {
@@ -336,11 +336,11 @@ namespace System.Text.Json
 
             int encodedLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length);
 
-            Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) - 7 - s_newLineLength);
+            Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - encodedLength - 7 - s_newLineLength);
 
             // 2 quotes for property name, 2 quotes to surround the base-64 encoded string value, 1 colon, and 1 space => indent + escapedPropertyName.Length + encodedLength + 6
-            // Optionally, 1 list separator, and 1-2 bytes for new line, with escaping which can by up to 6x.
-            int maxRequired = indent + escapedPropertyName.Length + (encodedLength * JsonConstants.MaxExpansionFactorWhileEscaping) + 7 + s_newLineLength;
+            // Optionally, 1 list separator, and 1-2 bytes for new line.
+            int maxRequired = indent + escapedPropertyName.Length + encodedLength + 7 + s_newLineLength;
 
             if (_memory.Length - BytesPending < maxRequired)
             {
index e83e3f2..06b09a3 100644 (file)
@@ -51,11 +51,11 @@ namespace System.Text.Json
         {
             int encodingLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length);
 
-            Debug.Assert(encodingLength < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping) - 3);
+            Debug.Assert(encodingLength < int.MaxValue - 3);
 
-            // 2 quotes to surround the base-64 encoded string value, with escaping which can by up to 6x.
+            // 2 quotes to surround the base-64 encoded string value.
             // Optionally, 1 list separator
-            int maxRequired = (encodingLength * JsonConstants.MaxExpansionFactorWhileEscaping) + 3;
+            int maxRequired = encodingLength + 3;
 
             if (_memory.Length - BytesPending < maxRequired)
             {
@@ -83,11 +83,11 @@ namespace System.Text.Json
 
             int encodingLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length);
 
-            Debug.Assert(encodingLength < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping) - indent - 3 - s_newLineLength);
+            Debug.Assert(encodingLength < int.MaxValue - indent - 3 - s_newLineLength);
 
-            // indentation + 2 quotes to surround the base-64 encoded string value, with escaping which can by up to 6x.
+            // indentation + 2 quotes to surround the base-64 encoded string value.
             // Optionally, 1 list separator, and 1-2 bytes for new line
-            int maxRequired = indent + (encodingLength * JsonConstants.MaxExpansionFactorWhileEscaping) + 3 + s_newLineLength;
+            int maxRequired = indent + encodingLength + 3 + s_newLineLength;
 
             if (_memory.Length - BytesPending < maxRequired)
             {
index 283a7c4..7afbce4 100644 (file)
@@ -50,19 +50,9 @@ namespace System.Text.Json
             encodedBytes = encodedBytes.Slice(0, written);
             Span<byte> destination = output.Slice(BytesPending);
 
-            int firstEscapeIndexVal = encodedBytes.IndexOfAny(JsonConstants.Plus, JsonConstants.Slash);
-            if (firstEscapeIndexVal == -1)
-            {
-                Debug.Assert(destination.Length >= written);
-                encodedBytes.Slice(0, written).CopyTo(destination);
-                BytesPending += written;
-            }
-            else
-            {
-                Debug.Assert(destination.Length >= written * JsonConstants.MaxExpansionFactorWhileEscaping);
-                JsonWriterHelper.EscapeString(encodedBytes, destination, firstEscapeIndexVal, _options.Encoder, out written);
-                BytesPending += written;
-            }
+            Debug.Assert(destination.Length >= written);
+            encodedBytes.Slice(0, written).CopyTo(destination);
+            BytesPending += written;
 
             if (outputText != null)
             {
index 13734aa..c6ab641 100644 (file)
@@ -2463,7 +2463,7 @@ namespace System.Text.Json.Tests
         }
 
         [Fact]
-        public void WriteBase64Escapes()
+        public void WriteBase64DoesNotEscape()
         {
             var output = new ArrayBufferWriter<byte>(10);
             using var jsonUtf8 = new Utf8JsonWriter(output);
@@ -2473,11 +2473,11 @@ namespace System.Text.Json.Tests
 
             jsonUtf8.Flush();
 
-            AssertContents("\"\\u002b\\u002b\\u002b\\u002b\"", output);
+            AssertContents("\"++++\"", output);
         }
 
         [Fact]
-        public void WriteBase64EscapesLarge()
+        public void WriteBase64DoesNotEscapeLarge()
         {
             var output = new ArrayBufferWriter<byte>(10);
             using var jsonUtf8 = new Utf8JsonWriter(output);