|
1 | 1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | 2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | 3 |
|
| 4 | +using System.Diagnostics; |
4 | 5 | using System.Runtime.CompilerServices; |
5 | | -using static System.Buffers.Text.Base64Helper; |
6 | 6 |
|
7 | 7 | namespace System.Buffers.Text |
8 | 8 | { |
@@ -94,33 +94,33 @@ public bool ValidateAndDecodeLength(char lastChar, int length, int paddingCount, |
94 | 94 | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
95 | 95 | public bool ValidateAndDecodeLength(byte lastChar, int length, int paddingCount, out int decodedLength) |
96 | 96 | { |
97 | | - // Padding is optional for Base64Url, so need to account remainder. If remainder is 1, then it's invalid. |
98 | | -#if NET |
99 | | - (uint whole, uint remainder) = uint.DivRem((uint)(length), 4); |
100 | | - if (remainder == 1 || (remainder > 1 && (remainder - paddingCount == 1 || paddingCount == remainder))) |
101 | | - { |
102 | | - decodedLength = 0; |
103 | | - return false; |
104 | | - } |
105 | | - |
106 | | - decodedLength = (int)((whole * 3) + (remainder > 0 ? remainder - 1 : 0) - paddingCount); |
107 | | -#else |
| 97 | + // Padding is optional for Base64Url, so need to account remainder. |
108 | 98 | int remainder = (int)((uint)length % 4); |
109 | | - if (remainder == 1 || (remainder > 1 && (remainder - paddingCount == 1 || paddingCount == remainder))) |
| 99 | + |
| 100 | + if (paddingCount != 0) |
110 | 101 | { |
111 | | - decodedLength = 0; |
112 | | - return false; |
| 102 | + length -= paddingCount; |
| 103 | + remainder = (int)((uint)length % 4); |
| 104 | + |
| 105 | + // if there is a padding, there should be remainder and the sum of remainder and padding should not exceed 4 |
| 106 | + if (remainder == 0 || remainder + paddingCount > 4) |
| 107 | + { |
| 108 | + decodedLength = 0; |
| 109 | + return false; |
| 110 | + } |
113 | 111 | } |
114 | 112 |
|
115 | | - decodedLength = (length >> 2) * 3 + (remainder > 0 ? remainder - 1 : 0) - paddingCount; |
116 | | -#endif |
117 | | - int decoded = default(Base64DecoderByte).DecodingMap[lastChar]; |
118 | | - if (((remainder == 3 || paddingCount == 1) && (decoded & 0x03) != 0) || |
119 | | - ((remainder == 2 || paddingCount == 2) && (decoded & 0x0F) != 0)) |
| 113 | + decodedLength = (length >> 2) * 3 + (remainder > 0 ? remainder - 1 : 0); |
| 114 | + |
| 115 | + if (remainder > 0) |
120 | 116 | { |
121 | | - // unused lower bits are not 0, reject input |
122 | | - decodedLength = 0; |
123 | | - return false; |
| 117 | + int decoded = default(Base64UrlDecoderByte).DecodingMap[lastChar]; |
| 118 | + switch (remainder) |
| 119 | + { |
| 120 | + case 1: return false; // 1 byte is not decodable => invalid. |
| 121 | + case 2: return ((decoded & 0x0F) == 0); // if unused lower 4 bits are set to 0 |
| 122 | + case 3: return ((decoded & 0x03) == 0); // if unused lower 2 bits are set to 0 |
| 123 | + } |
124 | 124 | } |
125 | 125 |
|
126 | 126 | return true; |
|
0 commit comments