mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-21 11:25:56 +01:00
Fix incompatible GUID conversions
This commit is contained in:
parent
41161864db
commit
c801b2fc3a
@ -1,15 +1,70 @@
|
||||
namespace Bit.Core.Utilities
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for converting between standard and raw GUID formats.
|
||||
///
|
||||
/// Note: Not optimized for performance. Don't use in performance-critical code.
|
||||
/// </summary>
|
||||
public static class GuidExtensions
|
||||
{
|
||||
public static string GuidToStandardFormat(this byte[] bytes)
|
||||
public static byte[] GuidToRawFormat(this string guidString)
|
||||
{
|
||||
return new Guid(bytes).ToString();
|
||||
if (guidString == null)
|
||||
{
|
||||
throw new ArgumentException("GUID parameter is null", nameof(guidString));
|
||||
}
|
||||
|
||||
if (!IsValidGuid(guidString)) {
|
||||
throw new FormatException("GUID parameter is invalid");
|
||||
}
|
||||
|
||||
var arr = new byte[16];
|
||||
|
||||
arr[0] = byte.Parse(guidString.Substring(0, 2), NumberStyles.HexNumber); // Parse ##......-....-....-....-............
|
||||
arr[1] = byte.Parse(guidString.Substring(2, 2), NumberStyles.HexNumber); // Parse ..##....-....-....-....-............
|
||||
arr[2] = byte.Parse(guidString.Substring(4, 2), NumberStyles.HexNumber); // Parse ....##..-....-....-....-............
|
||||
arr[3] = byte.Parse(guidString.Substring(6, 2), NumberStyles.HexNumber); // Parse ......##-....-....-....-............
|
||||
|
||||
arr[4] = byte.Parse(guidString.Substring(9, 2), NumberStyles.HexNumber); // Parse ........-##..-....-....-............
|
||||
arr[5] = byte.Parse(guidString.Substring(11, 2), NumberStyles.HexNumber); // Parse ........-..##-....-....-............
|
||||
|
||||
arr[6] = byte.Parse(guidString.Substring(14, 2), NumberStyles.HexNumber); // Parse ........-....-##..-....-............
|
||||
arr[7] = byte.Parse(guidString.Substring(16, 2), NumberStyles.HexNumber); // Parse ........-....-..##-....-............
|
||||
|
||||
arr[8] = byte.Parse(guidString.Substring(19, 2), NumberStyles.HexNumber); // Parse ........-....-....-##..-............
|
||||
arr[9] = byte.Parse(guidString.Substring(21, 2), NumberStyles.HexNumber); // Parse ........-....-....-..##-............
|
||||
|
||||
arr[10] = byte.Parse(guidString.Substring(24, 2), NumberStyles.HexNumber); // Parse ........-....-....-....-##..........
|
||||
arr[11] = byte.Parse(guidString.Substring(26, 2), NumberStyles.HexNumber); // Parse ........-....-....-....-..##........
|
||||
arr[12] = byte.Parse(guidString.Substring(28, 2), NumberStyles.HexNumber); // Parse ........-....-....-....-....##......
|
||||
arr[13] = byte.Parse(guidString.Substring(30, 2), NumberStyles.HexNumber); // Parse ........-....-....-....-......##....
|
||||
arr[14] = byte.Parse(guidString.Substring(32, 2), NumberStyles.HexNumber); // Parse ........-....-....-....-........##..
|
||||
arr[15] = byte.Parse(guidString.Substring(34, 2), NumberStyles.HexNumber); // Parse ........-....-....-....-..........##
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static byte[] GuidToRawFormat(this string guid)
|
||||
public static string GuidToStandardFormat(this byte[] guidBytes)
|
||||
{
|
||||
return Guid.Parse(guid).ToByteArray();
|
||||
if (guidBytes == null)
|
||||
{
|
||||
throw new ArgumentException("GUID parameter is null", nameof(guidBytes));
|
||||
}
|
||||
|
||||
if (guidBytes.Length != 16)
|
||||
{
|
||||
throw new ArgumentException("Invalid raw GUID format", nameof(guidBytes));
|
||||
}
|
||||
|
||||
return Convert.ToHexString(guidBytes).ToLower().Insert(8, "-").Insert(13, "-").Insert(18, "-").Insert(23, "-" );
|
||||
}
|
||||
|
||||
public static bool IsValidGuid(string guid)
|
||||
{
|
||||
return Regex.IsMatch(guid, @"^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$", RegexOptions.ECMAScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
81
test/Core.Test/Utilities/GuidExtensionsTests.cs
Normal file
81
test/Core.Test/Utilities/GuidExtensionsTests.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using Bit.Core.Utilities;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Utilities.Fido2
|
||||
{
|
||||
public class GuidExtensionsTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("59788da2-4221-4725-8503-52fea66df0b2", new byte[] {0x59, 0x78, 0x8d, 0xa2, 0x42, 0x21, 0x47, 0x25, 0x85, 0x03, 0x52, 0xfe, 0xa6, 0x6d, 0xf0, 0xb2})]
|
||||
[InlineData("e7895b55-2149-4cad-9e53-989192320a8a", new byte[] {0xe7, 0x89, 0x5b, 0x55, 0x21, 0x49, 0x4c, 0xad, 0x9e, 0x53, 0x98, 0x91, 0x92, 0x32, 0x0a, 0x8a})]
|
||||
[InlineData("d12f1371-5c89-4d20-a72f-0522674bdec7", new byte[] {0xd1, 0x2f, 0x13, 0x71, 0x5c, 0x89, 0x4d, 0x20, 0xa7, 0x2f, 0x05, 0x22, 0x67, 0x4b, 0xde, 0xc7})]
|
||||
[InlineData("040b76e4-aff1-4090-aaa2-7f781eb1f1ac", new byte[] {0x04, 0x0b, 0x76, 0xe4, 0xaf, 0xf1, 0x40, 0x90, 0xaa, 0xa2, 0x7f, 0x78, 0x1e, 0xb1, 0xf1, 0xac})]
|
||||
[InlineData("bda63808-9bf6-427b-97b6-37f3b8d8f0ea", new byte[] {0xbd, 0xa6, 0x38, 0x08, 0x9b, 0xf6, 0x42, 0x7b, 0x97, 0xb6, 0x37, 0xf3, 0xb8, 0xd8, 0xf0, 0xea})]
|
||||
[InlineData("5dfb0c92-0243-4c39-bf2b-29ffea097b96", new byte[] {0x5d, 0xfb, 0x0c, 0x92, 0x02, 0x43, 0x4c, 0x39, 0xbf, 0x2b, 0x29, 0xff, 0xea, 0x09, 0x7b, 0x96})]
|
||||
[InlineData("5a65a8aa-6b88-4c72-bc11-a8a80ba9431e", new byte[] {0x5a, 0x65, 0xa8, 0xaa, 0x6b, 0x88, 0x4c, 0x72, 0xbc, 0x11, 0xa8, 0xa8, 0x0b, 0xa9, 0x43, 0x1e})]
|
||||
[InlineData("76e7c061-892a-4740-a33c-2a52ea7ccb57", new byte[] {0x76, 0xe7, 0xc0, 0x61, 0x89, 0x2a, 0x47, 0x40, 0xa3, 0x3c, 0x2a, 0x52, 0xea, 0x7c, 0xcb, 0x57})]
|
||||
[InlineData("322d5ade-6f81-4d7e-ab9c-8155d9a6a50f", new byte[] {0x32, 0x2d, 0x5a, 0xde, 0x6f, 0x81, 0x4d, 0x7e, 0xab, 0x9c, 0x81, 0x55, 0xd9, 0xa6, 0xa5, 0x0f})]
|
||||
[InlineData("51927742-4e17-40af-991c-d958514ceedb", new byte[] {0x51, 0x92, 0x77, 0x42, 0x4e, 0x17, 0x40, 0xaf, 0x99, 0x1c, 0xd9, 0x58, 0x51, 0x4c, 0xee, 0xdb})]
|
||||
public void GuidToRawFormat_ReturnsRawFormat_GivenCorrectlyFormattedGuid(string standardFormat, byte[] rawFormat)
|
||||
{
|
||||
var result = GuidExtensions.GuidToRawFormat(standardFormat);
|
||||
|
||||
Assert.Equal(rawFormat, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("59788da-4221-4725-8503-52fea66df0b2")]
|
||||
[InlineData("e7895b552-149-4cad-9e53-989192320a8a")]
|
||||
[InlineData("x12f1371-5c89-4d20-a72f-0522674bdec7")]
|
||||
[InlineData("040b76e4-aff1-4090-Aaa2-7f781eb1f1ac")]
|
||||
[InlineData("bda63808-9bf6-427b-97b63-7f3b8d8f0ea")]
|
||||
[InlineData("")]
|
||||
public void GuidToRawFormat_ThrowsFormatException_IncorrectlyFormattedGuid(string standardFormat)
|
||||
{
|
||||
Assert.Throws<FormatException>(() => GuidExtensions.GuidToRawFormat(standardFormat));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GuidToRawFormat_ThrowsArgumentException_NullArgument()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => GuidExtensions.GuidToRawFormat(null));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] {0x59, 0x78, 0x8d, 0xa2, 0x42, 0x21, 0x47, 0x25, 0x85, 0x03, 0x52, 0xfe, 0xa6, 0x6d, 0xf0, 0xb2}, "59788da2-4221-4725-8503-52fea66df0b2")]
|
||||
[InlineData(new byte[] {0xe7, 0x89, 0x5b, 0x55, 0x21, 0x49, 0x4c, 0xad, 0x9e, 0x53, 0x98, 0x91, 0x92, 0x32, 0x0a, 0x8a}, "e7895b55-2149-4cad-9e53-989192320a8a")]
|
||||
[InlineData(new byte[] {0xd1, 0x2f, 0x13, 0x71, 0x5c, 0x89, 0x4d, 0x20, 0xa7, 0x2f, 0x05, 0x22, 0x67, 0x4b, 0xde, 0xc7}, "d12f1371-5c89-4d20-a72f-0522674bdec7")]
|
||||
[InlineData(new byte[] {0x04, 0x0b, 0x76, 0xe4, 0xaf, 0xf1, 0x40, 0x90, 0xaa, 0xa2, 0x7f, 0x78, 0x1e, 0xb1, 0xf1, 0xac}, "040b76e4-aff1-4090-aaa2-7f781eb1f1ac")]
|
||||
[InlineData(new byte[] {0xbd, 0xa6, 0x38, 0x08, 0x9b, 0xf6, 0x42, 0x7b, 0x97, 0xb6, 0x37, 0xf3, 0xb8, 0xd8, 0xf0, 0xea}, "bda63808-9bf6-427b-97b6-37f3b8d8f0ea")]
|
||||
[InlineData(new byte[] {0x5d, 0xfb, 0x0c, 0x92, 0x02, 0x43, 0x4c, 0x39, 0xbf, 0x2b, 0x29, 0xff, 0xea, 0x09, 0x7b, 0x96}, "5dfb0c92-0243-4c39-bf2b-29ffea097b96")]
|
||||
[InlineData(new byte[] {0x5a, 0x65, 0xa8, 0xaa, 0x6b, 0x88, 0x4c, 0x72, 0xbc, 0x11, 0xa8, 0xa8, 0x0b, 0xa9, 0x43, 0x1e}, "5a65a8aa-6b88-4c72-bc11-a8a80ba9431e")]
|
||||
[InlineData(new byte[] {0x76, 0xe7, 0xc0, 0x61, 0x89, 0x2a, 0x47, 0x40, 0xa3, 0x3c, 0x2a, 0x52, 0xea, 0x7c, 0xcb, 0x57}, "76e7c061-892a-4740-a33c-2a52ea7ccb57")]
|
||||
[InlineData(new byte[] {0x32, 0x2d, 0x5a, 0xde, 0x6f, 0x81, 0x4d, 0x7e, 0xab, 0x9c, 0x81, 0x55, 0xd9, 0xa6, 0xa5, 0x0f}, "322d5ade-6f81-4d7e-ab9c-8155d9a6a50f")]
|
||||
[InlineData(new byte[] {0x51, 0x92, 0x77, 0x42, 0x4e, 0x17, 0x40, 0xaf, 0x99, 0x1c, 0xd9, 0x58, 0x51, 0x4c, 0xee, 0xdb}, "51927742-4e17-40af-991c-d958514ceedb")]
|
||||
public void GuidToStandardFormat(byte[] rawFormat, string standardFormat)
|
||||
{
|
||||
var result = GuidExtensions.GuidToStandardFormat(rawFormat);
|
||||
|
||||
Assert.Equal(standardFormat, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GuidToStandardFormat_ThrowsArgumentException_NullArgument()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => GuidExtensions.GuidToStandardFormat(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GuidToStandardFormat_ThrowsArgumentException_TooLarge()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => GuidExtensions.GuidToStandardFormat(new byte[17]));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GuidToStandardFormat_ThrowsArgumentException_TooShort()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => GuidExtensions.GuidToStandardFormat(new byte[15]));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user