Skip to content

Commit

Permalink
Base64.Decode: fixed latent bug for non-ASCII inputs (#76795)
Browse files Browse the repository at this point in the history
  • Loading branch information
gfoidl authored Oct 10, 2022
1 parent 505c27e commit ef6bc67
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/libraries/System.Memory/tests/Base64/Base64DecoderUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,23 @@ public void BasicDecodingWithFinalBlockTrueKnownInputInvalid(string inputString,
Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));
}

[Theory]
[InlineData("\u00ecz/T", 0, 0)] // scalar code-path
[InlineData("z/Ta123\u00ec", 4, 3)]
[InlineData("\u00ecz/TpH7sqEkerqMweH1uSw==", 0, 0)] // Vector128 code-path
[InlineData("z/TpH7sqEkerqMweH1uSw\u00ec==", 20, 15)]
[InlineData("\u00ecz/TpH7sqEkerqMweH1uSw1a5ebaAF9xa8B0ze1wet4epo==", 0, 0)] // Vector256 / AVX code-path
[InlineData("z/TpH7sqEkerqMweH1uSw1a5ebaAF9xa8B0ze1wet4epo\u00ec==", 44, 33)]
public void BasicDecodingNonAsciiInputInvalid(string inputString, int expectedConsumed, int expectedWritten)
{
Span<byte> source = Encoding.UTF8.GetBytes(inputString);
Span<byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];

Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
Assert.Equal(expectedConsumed, consumed);
Assert.Equal(expectedWritten, decodedByteCount);
}

[Theory]
[InlineData("AQID", 3)]
[InlineData("AQIDBAUG", 6)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,8 +592,9 @@ private static unsafe void Vector128Decode(ref byte* srcBytes, ref byte* destByt

// lookup
Vector128<byte> hiNibbles = Vector128.ShiftRightLogical(str.AsInt32(), 4).AsByte() & mask2F;
Vector128<byte> loNibbles = str & mask2F;
Vector128<byte> hi = SimdShuffle(lutHi, hiNibbles, mask8F);
Vector128<byte> lo = SimdShuffle(lutLo, str, mask8F);
Vector128<byte> lo = SimdShuffle(lutLo, loNibbles, mask8F);

// Check for invalid input: if any "and" values from lo and hi are not zero,
// fall back on bytewise code to do error checking and reporting:
Expand Down

0 comments on commit ef6bc67

Please sign in to comment.