Fix the UUID structure to have distinct fields, as expected by

Breakpad’s minidump reader.

TEST=util_test UUID.UUID
R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/436933002
This commit is contained in:
Mark Mentovai 2014-08-01 16:10:58 -04:00
parent d2675ce50b
commit 5bbb7e8abb
3 changed files with 70 additions and 43 deletions

View File

@ -18,45 +18,37 @@
#include "base/basictypes.h"
#include "base/strings/stringprintf.h"
#include "util/stdlib/cxx.h"
#if CXX_LIBRARY_VERSION >= 2011
#include <type_traits>
#endif
#include "base/sys_byteorder.h"
namespace crashpad {
#if CXX_LIBRARY_VERSION >= 2011
COMPILE_ASSERT(std::is_standard_layout<UUID>::value,
UUID_must_be_standard_layout);
#endif
UUID::UUID() : data() {
UUID::UUID() : data_1(0), data_2(0), data_3(0), data_4(), data_5() {
}
UUID::UUID(const uint8_t* bytes) {
memcpy(data, bytes, sizeof(data));
InitializeFromBytes(bytes);
}
void UUID::InitializeFromBytes(const uint8_t* bytes) {
memcpy(this, bytes, sizeof(*this));
data_1 = base::NetToHost32(data_1);
data_2 = base::NetToHost16(data_2);
data_3 = base::NetToHost16(data_3);
}
std::string UUID::ToString() const {
return base::StringPrintf(
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
data[0],
data[1],
data[2],
data[3],
data[4],
data[5],
data[6],
data[7],
data[8],
data[9],
data[10],
data[11],
data[12],
data[13],
data[14],
data[15]);
return base::StringPrintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
data_1,
data_2,
data_3,
data_4[0],
data_4[1],
data_5[0],
data_5[1],
data_5[2],
data_5[3],
data_5[4],
data_5[5]);
}
} // namespace crashpad

View File

@ -27,25 +27,34 @@ namespace crashpad {
//! primarily by Microsoft.
//!
//! A %UUID is a unique 128-bit number specified by RFC 4122.
//!
//! This is a standard-layout structure, and it is acceptable to use `memcpy()`
//! to set its value.
struct UUID {
//! \brief Initializes the %UUID to zero.
UUID();
//! \copydoc InitializeFromBytes()
explicit UUID(const uint8_t* bytes);
//! \brief Initializes the %UUID from a sequence of bytes.
//!
//! \a bytes is taken as a %UUID laid out in big-endian format in memory. On
//! little-endian machines, appropriate byte-swapping will be performed to
//! initialize an objects data members.
//!
//! \param[in] bytes A buffer of exactly 16 bytes that will be assigned to the
//! %UUID.
explicit UUID(const uint8_t* bytes);
void InitializeFromBytes(const uint8_t* bytes);
//! \brief Formats the %UUID per RFC 4122 §3.
//!
//! \return A string of the form `"00112233-4455-6677-8899-aabbccddeeff"`.
std::string ToString() const;
uint8_t data[16];
// These fields are laid out according to RFC 4122 §4.1.2.
uint32_t data_1;
uint16_t data_2;
uint16_t data_3;
uint8_t data_4[2];
uint8_t data_5[6];
};
} // namespace crashpad

View File

@ -27,9 +27,17 @@ using namespace crashpad;
TEST(UUID, UUID) {
UUID uuid_zero;
for (size_t index = 0; index < 16; ++index) {
EXPECT_EQ(0u, uuid_zero.data[index]);
}
EXPECT_EQ(0u, uuid_zero.data_1);
EXPECT_EQ(0u, uuid_zero.data_2);
EXPECT_EQ(0u, uuid_zero.data_3);
EXPECT_EQ(0u, uuid_zero.data_4[0]);
EXPECT_EQ(0u, uuid_zero.data_4[1]);
EXPECT_EQ(0u, uuid_zero.data_5[0]);
EXPECT_EQ(0u, uuid_zero.data_5[1]);
EXPECT_EQ(0u, uuid_zero.data_5[2]);
EXPECT_EQ(0u, uuid_zero.data_5[3]);
EXPECT_EQ(0u, uuid_zero.data_5[4]);
EXPECT_EQ(0u, uuid_zero.data_5[5]);
EXPECT_EQ("00000000-0000-0000-0000-000000000000", uuid_zero.ToString());
const uint8_t kBytes[16] = {0x00,
@ -49,12 +57,19 @@ TEST(UUID, UUID) {
0x0e,
0x0f};
UUID uuid(kBytes);
for (size_t index = 0; index < arraysize(kBytes); ++index) {
EXPECT_EQ(kBytes[index], uuid.data[index]);
}
EXPECT_EQ(0x00010203u, uuid.data_1);
EXPECT_EQ(0x0405u, uuid.data_2);
EXPECT_EQ(0x0607u, uuid.data_3);
EXPECT_EQ(0x08u, uuid.data_4[0]);
EXPECT_EQ(0x09u, uuid.data_4[1]);
EXPECT_EQ(0x0au, uuid.data_5[0]);
EXPECT_EQ(0x0bu, uuid.data_5[1]);
EXPECT_EQ(0x0cu, uuid.data_5[2]);
EXPECT_EQ(0x0du, uuid.data_5[3]);
EXPECT_EQ(0x0eu, uuid.data_5[4]);
EXPECT_EQ(0x0fu, uuid.data_5[5]);
EXPECT_EQ("00010203-0405-0607-0809-0a0b0c0d0e0f", uuid.ToString());
// UUID is a standard-layout structure. It is valid to memcpy to it.
const uint8_t kMoreBytes[16] = {0xff,
0xee,
0xdd,
@ -71,7 +86,18 @@ TEST(UUID, UUID) {
0x22,
0x11,
0x00};
memcpy(&uuid, kMoreBytes, sizeof(kMoreBytes));
uuid.InitializeFromBytes(kMoreBytes);
EXPECT_EQ(0xffeeddccu, uuid.data_1);
EXPECT_EQ(0xbbaau, uuid.data_2);
EXPECT_EQ(0x9988u, uuid.data_3);
EXPECT_EQ(0x77u, uuid.data_4[0]);
EXPECT_EQ(0x66u, uuid.data_4[1]);
EXPECT_EQ(0x55u, uuid.data_5[0]);
EXPECT_EQ(0x44u, uuid.data_5[1]);
EXPECT_EQ(0x33u, uuid.data_5[2]);
EXPECT_EQ(0x22u, uuid.data_5[3]);
EXPECT_EQ(0x11u, uuid.data_5[4]);
EXPECT_EQ(0x00u, uuid.data_5[5]);
EXPECT_EQ("ffeeddcc-bbaa-9988-7766-554433221100", uuid.ToString());
}