diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Base64Transforms.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Base64Transforms.cs index 561dd327e92dc0..6526ba7db54245 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Base64Transforms.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Base64Transforms.cs @@ -189,6 +189,7 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input if (inputCount == 0) { + Reset(); return Array.Empty(); } diff --git a/src/libraries/System.Security.Cryptography/tests/Base64TransformsTests.cs b/src/libraries/System.Security.Cryptography/tests/Base64TransformsTests.cs index 23f83f032ddd43..f2ee2251c400e9 100644 --- a/src/libraries/System.Security.Cryptography/tests/Base64TransformsTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Base64TransformsTests.cs @@ -439,5 +439,36 @@ public void TransformBlock_OutputBufferTooSmall_ThrowsArgumentOutOfRangeExceptio AssertExtensions.Throws("outputBuffer", () => transform.TransformBlock(block, 0, block.Length, destination, 0)); } + + [Theory] + [InlineData(0)] + [InlineData(1)] + public void TransformFinalBlock_ShouldResetStateConsistently(int finalBlockSize) + { + using FromBase64Transform transform = new(); + byte[] destination = new byte[2048]; + byte[] partialBlock = [(byte)'A']; + byte[] finalBlock = new byte[finalBlockSize]; + finalBlock.AsSpan().Fill((byte)'A'); + + // First, do a TransformBlock with a partial block of one unit + transform.TransformBlock(partialBlock, 0, partialBlock.Length, destination, 0); + + // Call TransformFinalBlock with either zero or one input + // This still results in a partial block (we need four for a complete block) + byte[] transformed = transform.TransformFinalBlock(finalBlock, 0, finalBlockSize); + + // The transform should return an empty buffer for partial blocks + Assert.Empty(transformed); + + // Now try to reuse the transform with a complete block + // This should succeed without observing leftover data from before + byte[] complete = Text.Encoding.UTF8.GetBytes(Convert.ToBase64String("Hello World"u8.ToArray())); + transformed = transform.TransformFinalBlock(complete, 0, complete.Length); + + // Verify we get the expected output + string result = Text.Encoding.UTF8.GetString(transformed); + Assert.Equal("Hello World", result); + } } }