Fixed the UUID generation logic so that the variant digit is RFC 4122 (#4554)
conforming.
This commit is contained in:
parent
1ae675a1bb
commit
f166699120
@ -12,6 +12,7 @@ This is useful when the UUID was generated outside the Azure SDK, or needs to be
|
||||
### Bugs Fixed
|
||||
|
||||
- [[#4490]](https://github.com/Azure/azure-sdk-for-cpp/issues/4490) Fixed WinHTTP memory leak during failed requests.
|
||||
- Fixed the UUID generation so the variant is RFC 4122 conforming.
|
||||
|
||||
### Other Changes
|
||||
|
||||
|
||||
@ -24,11 +24,6 @@ namespace Azure { namespace Core {
|
||||
static constexpr size_t UuidSize = 16;
|
||||
|
||||
std::array<uint8_t, UuidSize> m_uuid;
|
||||
// The UUID reserved variants.
|
||||
static constexpr uint8_t ReservedNCS = 0x80;
|
||||
static constexpr uint8_t ReservedRFC4122 = 0x40;
|
||||
static constexpr uint8_t ReservedMicrosoft = 0x20;
|
||||
static constexpr uint8_t ReservedFuture = 0x00;
|
||||
|
||||
private:
|
||||
Uuid(uint8_t const uuid[UuidSize]) { std::memcpy(m_uuid.data(), uuid, UuidSize); }
|
||||
|
||||
@ -67,8 +67,15 @@ namespace Azure { namespace Core {
|
||||
std::memcpy(uuid + i, &x, 4);
|
||||
}
|
||||
|
||||
// SetVariant to ReservedRFC4122
|
||||
uuid[8] = (uuid[8] | ReservedRFC4122) & 0x7F;
|
||||
// The variant field consists of a variable number of the most significant bits of octet 8 of
|
||||
// the UUID.
|
||||
// https://www.rfc-editor.org/rfc/rfc4122.html#section-4.1.1
|
||||
// For setting the variant to conform to RFC4122, the high bits need to be of the form 10xx,
|
||||
// which means the hex value of the first 4 bits can only be either 8, 9, A|a, B|b. The 0-7
|
||||
// values are reserved for backward compatibility. The C|c, D|d values are reserved for
|
||||
// Microsoft, and the E|e, F|f values are reserved for future use.
|
||||
// Therefore, we have to zero out the two high bits, and then set the highest bit to 1.
|
||||
uuid[8] = (uuid[8] & 0x3F) | 0x80;
|
||||
|
||||
constexpr uint8_t version = 4; // Version 4: Pseudo-random number
|
||||
|
||||
|
||||
@ -36,6 +36,33 @@ TEST(Uuid, Randomness)
|
||||
EXPECT_EQ(uuids.size(), size);
|
||||
}
|
||||
|
||||
TEST(Uuid, Rfc4122Conforming)
|
||||
{
|
||||
const int size = 100;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
auto uuid = Uuid::CreateUuid();
|
||||
auto uuidStr = uuid.ToString();
|
||||
auto version = uuidStr[14];
|
||||
EXPECT_EQ(version, '4'); // Version 4: Pseudo-random number
|
||||
|
||||
// The variant field consists of a variable number of the most significant bits of octet 8 of
|
||||
// the UUID.
|
||||
// https://www.rfc-editor.org/rfc/rfc4122.html#section-4.1.1
|
||||
// The high bits of the variant need to be of the form 10xx, which means they can only be either
|
||||
// 8, 9, A|a, B|b. The 0-7 values are reserved for backward compatibility. The C|c, D|d values
|
||||
// are reserved for Microsoft, and the E|e, F|f values are reserved for future use.
|
||||
auto variant = uuidStr[19];
|
||||
|
||||
// The test is written this way to improve logging IF it was to fail, so we can see the value
|
||||
// of the incorrect variant.
|
||||
EXPECT_TRUE(
|
||||
(variant == '8' || variant == '9' || variant == 'A' || variant == 'B' || variant == 'a'
|
||||
|| variant == 'b'))
|
||||
<< variant << " is not one of the expected values of 8, 9, A, B, a, b";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Uuid, separatorPosition)
|
||||
{
|
||||
auto uuidKey = Uuid::CreateUuid().ToString();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user