Remove Microsoft.Extensions.WebEncoders.Sources
\n\nCommit migrated from e7bb41b9bf
This commit is contained in:
parent
cb018faf53
commit
4fcd97e4d2
|
|
@ -1,38 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.WebEncoders.Sources
|
|
||||||
{
|
|
||||||
// TODO using a resx file. project.json, unfortunately, fails to embed resx files when there are also compile items
|
|
||||||
// in the contentFiles section. Revisit once we convert repos to MSBuild
|
|
||||||
internal static class EncoderResources
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Invalid {0}, {1} or {2} length.
|
|
||||||
/// </summary>
|
|
||||||
internal static readonly string WebEncoders_InvalidCountOffsetOrLength = "Invalid {0}, {1} or {2} length.";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Malformed input: {0} is an invalid input length.
|
|
||||||
/// </summary>
|
|
||||||
internal static readonly string WebEncoders_MalformedInput = "Malformed input: {0} is an invalid input length.";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invalid {0}, {1} or {2} length.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatWebEncoders_InvalidCountOffsetOrLength(object p0, object p1, object p2)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, WebEncoders_InvalidCountOffsetOrLength, p0, p1, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Malformed input: {0} is an invalid input length.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatWebEncoders_MalformedInput(object p0)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, WebEncoders_MalformedInput, p0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,388 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
|
||||||
using Microsoft.Extensions.WebEncoders.Sources;
|
|
||||||
|
|
||||||
#if WebEncoders_In_WebUtilities
|
|
||||||
namespace Microsoft.AspNetCore.WebUtilities
|
|
||||||
#else
|
|
||||||
namespace Microsoft.Extensions.Internal
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Contains utility APIs to assist with common encoding and decoding operations.
|
|
||||||
/// </summary>
|
|
||||||
#if WebEncoders_In_WebUtilities
|
|
||||||
public
|
|
||||||
#else
|
|
||||||
internal
|
|
||||||
#endif
|
|
||||||
static class WebEncoders
|
|
||||||
{
|
|
||||||
private static readonly byte[] EmptyBytes = new byte[0];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Decodes a base64url-encoded string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The base64url-encoded input to decode.</param>
|
|
||||||
/// <returns>The base64url-decoded form of the input.</returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// The input must not contain any whitespace or padding characters.
|
|
||||||
/// Throws <see cref="FormatException"/> if the input is malformed.
|
|
||||||
/// </remarks>
|
|
||||||
public static byte[] Base64UrlDecode(string input)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Base64UrlDecode(input, offset: 0, count: input.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Decodes a base64url-encoded substring of a given string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">A string containing the base64url-encoded input to decode.</param>
|
|
||||||
/// <param name="offset">The position in <paramref name="input"/> at which decoding should begin.</param>
|
|
||||||
/// <param name="count">The number of characters in <paramref name="input"/> to decode.</param>
|
|
||||||
/// <returns>The base64url-decoded form of the input.</returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// The input must not contain any whitespace or padding characters.
|
|
||||||
/// Throws <see cref="FormatException"/> if the input is malformed.
|
|
||||||
/// </remarks>
|
|
||||||
public static byte[] Base64UrlDecode(string input, int offset, int count)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateParameters(input.Length, nameof(input), offset, count);
|
|
||||||
|
|
||||||
// Special-case empty input
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
return EmptyBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create array large enough for the Base64 characters, not just shorter Base64-URL-encoded form.
|
|
||||||
var buffer = new char[GetArraySizeRequiredToDecode(count)];
|
|
||||||
|
|
||||||
return Base64UrlDecode(input, offset, buffer, bufferOffset: 0, count: count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Decodes a base64url-encoded <paramref name="input"/> into a <c>byte[]</c>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">A string containing the base64url-encoded input to decode.</param>
|
|
||||||
/// <param name="offset">The position in <paramref name="input"/> at which decoding should begin.</param>
|
|
||||||
/// <param name="buffer">
|
|
||||||
/// Scratch buffer to hold the <see cref="char"/>s to decode. Array must be large enough to hold
|
|
||||||
/// <paramref name="bufferOffset"/> and <paramref name="count"/> characters as well as Base64 padding
|
|
||||||
/// characters. Content is not preserved.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="bufferOffset">
|
|
||||||
/// The offset into <paramref name="buffer"/> at which to begin writing the <see cref="char"/>s to decode.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="count">The number of characters in <paramref name="input"/> to decode.</param>
|
|
||||||
/// <returns>The base64url-decoded form of the <paramref name="input"/>.</returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// The input must not contain any whitespace or padding characters.
|
|
||||||
/// Throws <see cref="FormatException"/> if the input is malformed.
|
|
||||||
/// </remarks>
|
|
||||||
public static byte[] Base64UrlDecode(string input, int offset, char[] buffer, int bufferOffset, int count)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(input));
|
|
||||||
}
|
|
||||||
if (buffer == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateParameters(input.Length, nameof(input), offset, count);
|
|
||||||
if (bufferOffset < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(bufferOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
return EmptyBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assumption: input is base64url encoded without padding and contains no whitespace.
|
|
||||||
|
|
||||||
var paddingCharsToAdd = GetNumBase64PaddingCharsToAddForDecode(count);
|
|
||||||
var arraySizeRequired = checked(count + paddingCharsToAdd);
|
|
||||||
Debug.Assert(arraySizeRequired % 4 == 0, "Invariant: Array length must be a multiple of 4.");
|
|
||||||
|
|
||||||
if (buffer.Length - bufferOffset < arraySizeRequired)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(
|
|
||||||
string.Format(
|
|
||||||
CultureInfo.CurrentCulture,
|
|
||||||
EncoderResources.WebEncoders_InvalidCountOffsetOrLength,
|
|
||||||
nameof(count),
|
|
||||||
nameof(bufferOffset),
|
|
||||||
nameof(input)),
|
|
||||||
nameof(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy input into buffer, fixing up '-' -> '+' and '_' -> '/'.
|
|
||||||
var i = bufferOffset;
|
|
||||||
for (var j = offset; i - bufferOffset < count; i++, j++)
|
|
||||||
{
|
|
||||||
var ch = input[j];
|
|
||||||
if (ch == '-')
|
|
||||||
{
|
|
||||||
buffer[i] = '+';
|
|
||||||
}
|
|
||||||
else if (ch == '_')
|
|
||||||
{
|
|
||||||
buffer[i] = '/';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buffer[i] = ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the padding characters back.
|
|
||||||
for (; paddingCharsToAdd > 0; i++, paddingCharsToAdd--)
|
|
||||||
{
|
|
||||||
buffer[i] = '=';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode.
|
|
||||||
// If the caller provided invalid base64 chars, they'll be caught here.
|
|
||||||
return Convert.FromBase64CharArray(buffer, bufferOffset, arraySizeRequired);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the minimum <c>char[]</c> size required for decoding of <paramref name="count"/> characters
|
|
||||||
/// with the <see cref="Base64UrlDecode(string, int, char[], int, int)"/> method.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="count">The number of characters to decode.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// The minimum <c>char[]</c> size required for decoding of <paramref name="count"/> characters.
|
|
||||||
/// </returns>
|
|
||||||
public static int GetArraySizeRequiredToDecode(int count)
|
|
||||||
{
|
|
||||||
if (count < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var numPaddingCharsToAdd = GetNumBase64PaddingCharsToAddForDecode(count);
|
|
||||||
|
|
||||||
return checked(count + numPaddingCharsToAdd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Encodes <paramref name="input"/> using base64url encoding.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The binary input to encode.</param>
|
|
||||||
/// <returns>The base64url-encoded form of <paramref name="input"/>.</returns>
|
|
||||||
public static string Base64UrlEncode(byte[] input)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Base64UrlEncode(input, offset: 0, count: input.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Encodes <paramref name="input"/> using base64url encoding.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The binary input to encode.</param>
|
|
||||||
/// <param name="offset">The offset into <paramref name="input"/> at which to begin encoding.</param>
|
|
||||||
/// <param name="count">The number of bytes from <paramref name="input"/> to encode.</param>
|
|
||||||
/// <returns>The base64url-encoded form of <paramref name="input"/>.</returns>
|
|
||||||
public static string Base64UrlEncode(byte[] input, int offset, int count)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateParameters(input.Length, nameof(input), offset, count);
|
|
||||||
|
|
||||||
// Special-case empty input
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
var buffer = new char[GetArraySizeRequiredToEncode(count)];
|
|
||||||
var numBase64Chars = Base64UrlEncode(input, offset, buffer, outputOffset: 0, count: count);
|
|
||||||
|
|
||||||
return new String(buffer, startIndex: 0, length: numBase64Chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Encodes <paramref name="input"/> using base64url encoding.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The binary input to encode.</param>
|
|
||||||
/// <param name="offset">The offset into <paramref name="input"/> at which to begin encoding.</param>
|
|
||||||
/// <param name="output">
|
|
||||||
/// Buffer to receive the base64url-encoded form of <paramref name="input"/>. Array must be large enough to
|
|
||||||
/// hold <paramref name="outputOffset"/> characters and the full base64-encoded form of
|
|
||||||
/// <paramref name="input"/>, including padding characters.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="outputOffset">
|
|
||||||
/// The offset into <paramref name="output"/> at which to begin writing the base64url-encoded form of
|
|
||||||
/// <paramref name="input"/>.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="count">The number of <c>byte</c>s from <paramref name="input"/> to encode.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// The number of characters written to <paramref name="output"/>, less any padding characters.
|
|
||||||
/// </returns>
|
|
||||||
public static int Base64UrlEncode(byte[] input, int offset, char[] output, int outputOffset, int count)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(input));
|
|
||||||
}
|
|
||||||
if (output == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(output));
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateParameters(input.Length, nameof(input), offset, count);
|
|
||||||
if (outputOffset < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(outputOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
var arraySizeRequired = GetArraySizeRequiredToEncode(count);
|
|
||||||
if (output.Length - outputOffset < arraySizeRequired)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(
|
|
||||||
string.Format(
|
|
||||||
CultureInfo.CurrentCulture,
|
|
||||||
EncoderResources.WebEncoders_InvalidCountOffsetOrLength,
|
|
||||||
nameof(count),
|
|
||||||
nameof(outputOffset),
|
|
||||||
nameof(output)),
|
|
||||||
nameof(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special-case empty input.
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use base64url encoding with no padding characters. See RFC 4648, Sec. 5.
|
|
||||||
|
|
||||||
// Start with default Base64 encoding.
|
|
||||||
var numBase64Chars = Convert.ToBase64CharArray(input, offset, count, output, outputOffset);
|
|
||||||
|
|
||||||
// Fix up '+' -> '-' and '/' -> '_'. Drop padding characters.
|
|
||||||
for (var i = outputOffset; i - outputOffset < numBase64Chars; i++)
|
|
||||||
{
|
|
||||||
var ch = output[i];
|
|
||||||
if (ch == '+')
|
|
||||||
{
|
|
||||||
output[i] = '-';
|
|
||||||
}
|
|
||||||
else if (ch == '/')
|
|
||||||
{
|
|
||||||
output[i] = '_';
|
|
||||||
}
|
|
||||||
else if (ch == '=')
|
|
||||||
{
|
|
||||||
// We've reached a padding character; truncate the remainder.
|
|
||||||
return i - outputOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return numBase64Chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the minimum output <c>char[]</c> size required for encoding <paramref name="count"/>
|
|
||||||
/// <see cref="byte"/>s with the <see cref="Base64UrlEncode(byte[], int, char[], int, int)"/> method.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="count">The number of characters to encode.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// The minimum output <c>char[]</c> size required for encoding <paramref name="count"/> <see cref="byte"/>s.
|
|
||||||
/// </returns>
|
|
||||||
public static int GetArraySizeRequiredToEncode(int count)
|
|
||||||
{
|
|
||||||
var numWholeOrPartialInputBlocks = checked(count + 2) / 3;
|
|
||||||
return checked(numWholeOrPartialInputBlocks * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetNumBase64PaddingCharsInString(string str)
|
|
||||||
{
|
|
||||||
// Assumption: input contains a well-formed base64 string with no whitespace.
|
|
||||||
|
|
||||||
// base64 guaranteed have 0 - 2 padding characters.
|
|
||||||
if (str[str.Length - 1] == '=')
|
|
||||||
{
|
|
||||||
if (str[str.Length - 2] == '=')
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetNumBase64PaddingCharsToAddForDecode(int inputLength)
|
|
||||||
{
|
|
||||||
switch (inputLength % 4)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return 0;
|
|
||||||
case 2:
|
|
||||||
return 2;
|
|
||||||
case 3:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
throw new FormatException(
|
|
||||||
string.Format(
|
|
||||||
CultureInfo.CurrentCulture,
|
|
||||||
EncoderResources.WebEncoders_MalformedInput,
|
|
||||||
inputLength));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ValidateParameters(int bufferLength, string inputName, int offset, int count)
|
|
||||||
{
|
|
||||||
if (offset < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(offset));
|
|
||||||
}
|
|
||||||
if (count < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(count));
|
|
||||||
}
|
|
||||||
if (bufferLength - offset < count)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(
|
|
||||||
string.Format(
|
|
||||||
CultureInfo.CurrentCulture,
|
|
||||||
EncoderResources.WebEncoders_InvalidCountOffsetOrLength,
|
|
||||||
nameof(count),
|
|
||||||
nameof(offset),
|
|
||||||
inputName),
|
|
||||||
nameof(count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.Internal
|
|
||||||
{
|
|
||||||
public class WebEncodersTests
|
|
||||||
{
|
|
||||||
[Theory]
|
|
||||||
[InlineData("", 1, 0)]
|
|
||||||
[InlineData("", 0, 1)]
|
|
||||||
[InlineData("0123456789", 9, 2)]
|
|
||||||
[InlineData("0123456789", Int32.MaxValue, 2)]
|
|
||||||
[InlineData("0123456789", 9, -1)]
|
|
||||||
public void Base64UrlDecode_BadOffsets(string input, int offset, int count)
|
|
||||||
{
|
|
||||||
// Act & assert
|
|
||||||
Assert.ThrowsAny<ArgumentException>(() =>
|
|
||||||
{
|
|
||||||
var retVal = WebEncoders.Base64UrlDecode(input, offset, count);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("x")]
|
|
||||||
[InlineData("(x)")]
|
|
||||||
public void Base64UrlDecode_MalformedInput(string input)
|
|
||||||
{
|
|
||||||
// Act & assert
|
|
||||||
Assert.Throws<FormatException>(() =>
|
|
||||||
{
|
|
||||||
var retVal = WebEncoders.Base64UrlDecode(input);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("", "")]
|
|
||||||
[InlineData("123456qwerty++//X+/x", "123456qwerty--__X-_x")]
|
|
||||||
[InlineData("123456qwerty++//X+/xxw==", "123456qwerty--__X-_xxw")]
|
|
||||||
[InlineData("123456qwerty++//X+/xxw0=", "123456qwerty--__X-_xxw0")]
|
|
||||||
public void Base64UrlEncode_And_Decode(string base64Input, string expectedBase64Url)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
byte[] input = new byte[3].Concat(Convert.FromBase64String(base64Input)).Concat(new byte[2]).ToArray();
|
|
||||||
|
|
||||||
// Act & assert - 1
|
|
||||||
string actualBase64Url = WebEncoders.Base64UrlEncode(input, 3, input.Length - 5); // also helps test offsets
|
|
||||||
Assert.Equal(expectedBase64Url, actualBase64Url);
|
|
||||||
|
|
||||||
// Act & assert - 2
|
|
||||||
// Verify that values round-trip
|
|
||||||
byte[] roundTripped = WebEncoders.Base64UrlDecode("xx" + actualBase64Url + "yyy", 2, actualBase64Url.Length); // also helps test offsets
|
|
||||||
string roundTrippedAsBase64 = Convert.ToBase64String(roundTripped);
|
|
||||||
Assert.Equal(roundTrippedAsBase64, base64Input);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("", "")]
|
|
||||||
[InlineData("123456qwerty++//X+/x", "123456qwerty--__X-_x")]
|
|
||||||
[InlineData("123456qwerty++//X+/xxw==", "123456qwerty--__X-_xxw")]
|
|
||||||
[InlineData("123456qwerty++//X+/xxw0=", "123456qwerty--__X-_xxw0")]
|
|
||||||
public void Base64UrlEncode_And_Decode_WithBufferOffsets(string base64Input, string expectedBase64Url)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var input = new byte[3].Concat(Convert.FromBase64String(base64Input)).Concat(new byte[2]).ToArray();
|
|
||||||
var buffer = new char[30];
|
|
||||||
var output = new char[30];
|
|
||||||
for (var i = 0; i < buffer.Length; i++)
|
|
||||||
{
|
|
||||||
buffer[i] = '^';
|
|
||||||
output[i] = '^';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Act 1
|
|
||||||
var numEncodedChars =
|
|
||||||
WebEncoders.Base64UrlEncode(input, offset: 3, output: output, outputOffset: 4, count: input.Length - 5);
|
|
||||||
|
|
||||||
// Assert 1
|
|
||||||
var encodedString = new string(output, startIndex: 4, length: numEncodedChars);
|
|
||||||
Assert.Equal(expectedBase64Url, encodedString);
|
|
||||||
|
|
||||||
// Act 2
|
|
||||||
var roundTripInput = new string(output);
|
|
||||||
var roundTripped =
|
|
||||||
WebEncoders.Base64UrlDecode(roundTripInput, offset: 4, buffer: buffer, bufferOffset: 5, count: numEncodedChars);
|
|
||||||
|
|
||||||
// Assert 2, verify that values round-trip
|
|
||||||
var roundTrippedAsBase64 = Convert.ToBase64String(roundTripped);
|
|
||||||
Assert.Equal(roundTrippedAsBase64, base64Input);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(0, 1, 0)]
|
|
||||||
[InlineData(0, 0, 1)]
|
|
||||||
[InlineData(10, 9, 2)]
|
|
||||||
[InlineData(10, Int32.MaxValue, 2)]
|
|
||||||
[InlineData(10, 9, -1)]
|
|
||||||
public void Base64UrlEncode_BadOffsets(int inputLength, int offset, int count)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
byte[] input = new byte[inputLength];
|
|
||||||
|
|
||||||
// Act & assert
|
|
||||||
Assert.ThrowsAny<ArgumentException>(() =>
|
|
||||||
{
|
|
||||||
var retVal = WebEncoders.Base64UrlEncode(input, offset, count);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue