mirror of
https://github.com/chromium/crashpad.git
synced 2025-01-13 16:58:04 +08:00
Add UUID, c16lcpy (strlcpy for char16*), and their tests to util.
These are dependencies of the upcoming MinidumpStringWriter. R=rsesek@chromium.org Review URL: https://codereview.chromium.org/430003003
This commit is contained in:
parent
5ba343ccf1
commit
4d6b867a1f
62
util/misc/uuid.cc
Normal file
62
util/misc/uuid.cc
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/misc/uuid.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "util/stdlib/cxx.h"
|
||||
|
||||
#if CXX_LIBRARY_VERSION >= 2011
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
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(const uint8_t* bytes) {
|
||||
memcpy(data, bytes, sizeof(data));
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
53
util/misc/uuid.h
Normal file
53
util/misc/uuid.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_UTIL_MISC_UUID_H_
|
||||
#define CRASHPAD_UTIL_MISC_UUID_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief A universally unique identifier (%UUID).
|
||||
//!
|
||||
//! An alternate term for %UUID is “globally unique identifier” (GUID), used
|
||||
//! 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();
|
||||
|
||||
//! \brief Initializes the %UUID from a sequence of bytes.
|
||||
//!
|
||||
//! \param[in] bytes A buffer of exactly 16 bytes that will be assigned to the
|
||||
//! %UUID.
|
||||
explicit UUID(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];
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_UTIL_MISC_UUID_H_
|
78
util/misc/uuid_test.cc
Normal file
78
util/misc/uuid_test.cc
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/misc/uuid.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
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("00000000-0000-0000-0000-000000000000", uuid_zero.ToString());
|
||||
|
||||
const uint8_t kBytes[16] = {0x00,
|
||||
0x01,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
0x06,
|
||||
0x07,
|
||||
0x08,
|
||||
0x09,
|
||||
0x0a,
|
||||
0x0b,
|
||||
0x0c,
|
||||
0x0d,
|
||||
0x0e,
|
||||
0x0f};
|
||||
UUID uuid(kBytes);
|
||||
for (size_t index = 0; index < arraysize(kBytes); ++index) {
|
||||
EXPECT_EQ(kBytes[index], uuid.data[index]);
|
||||
}
|
||||
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,
|
||||
0xcc,
|
||||
0xbb,
|
||||
0xaa,
|
||||
0x99,
|
||||
0x88,
|
||||
0x77,
|
||||
0x66,
|
||||
0x55,
|
||||
0x44,
|
||||
0x33,
|
||||
0x22,
|
||||
0x11,
|
||||
0x00};
|
||||
memcpy(&uuid, kMoreBytes, sizeof(kMoreBytes));
|
||||
EXPECT_EQ("ffeeddcc-bbaa-9988-7766-554433221100", uuid.ToString());
|
||||
}
|
||||
|
||||
} // namespace
|
57
util/stdlib/cxx.h
Normal file
57
util/stdlib/cxx.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_UTIL_STDLIB_CXX_H_
|
||||
#define CRASHPAD_UTIL_STDLIB_CXX_H_
|
||||
|
||||
// <ciso646> doesn’t do very much, and under libc++, it will cause the
|
||||
// _LIBCPP_VERSION macro to be defined properly. Under libstdc++, it doesn’t
|
||||
// cause __GLIBCXX__ to be defined, but if _LIBCPP_VERSION isn’t defined after
|
||||
// #including <ciso646>, assume libstdc++ and #include libstdc++’s internal
|
||||
// header that defines __GLIBCXX__.
|
||||
|
||||
#include <ciso646>
|
||||
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<bits/c++config.h>)
|
||||
#include <bits/c++config.h>
|
||||
#endif
|
||||
#else
|
||||
#include <bits/c++config.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// libstdc++ does not identify its version directly, but identifies the GCC
|
||||
// package it is a part of via the __GLIBCXX__ macro, which is based on the date
|
||||
// of the GCC release. libstdc++ had sufficient C++11 support as of GCC 4.6.0,
|
||||
// __GLIBCXX__ 20110325, but maintenance releases in the 4.4 an 4.5 series
|
||||
// followed this date, so check for those versions by their date stamps.
|
||||
// http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning
|
||||
//
|
||||
// libc++, identified by _LIBCPP_VERSION, always supports C++11.
|
||||
#if __cplusplus >= 201103l && \
|
||||
((defined(__GLIBCXX__) && \
|
||||
__GLIBCXX__ >= 20110325ul && /* GCC >= 4.6.0 */ \
|
||||
__GLIBCXX__ != 20110416ul && /* GCC 4.4.6 */ \
|
||||
__GLIBCXX__ != 20120313ul && /* GCC 4.4.7 */ \
|
||||
__GLIBCXX__ != 20110428ul && /* GCC 4.5.3 */ \
|
||||
__GLIBCXX__ != 20120702ul) || /* GCC 4.5.4 */ \
|
||||
(defined(_LIBCPP_VERSION)))
|
||||
#define CXX_LIBRARY_VERSION 2011
|
||||
#else
|
||||
#define CXX_LIBRARY_VERSION 2003
|
||||
#endif
|
||||
|
||||
#endif // CRASHPAD_UTIL_STDLIB_CXX_H_
|
30
util/stdlib/strlcpy.cc
Normal file
30
util/stdlib/strlcpy.cc
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/stdlib/strlcpy.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
size_t c16lcpy(char16* destination, const char16* source, size_t length) {
|
||||
size_t source_length = base::c16len(source);
|
||||
if (source_length < length) {
|
||||
base::c16memcpy(destination, source, source_length + 1);
|
||||
} else if (length != 0) {
|
||||
base::c16memcpy(destination, source, length - 1);
|
||||
destination[length - 1] = '\0';
|
||||
}
|
||||
return source_length;
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
52
util/stdlib/strlcpy.h
Normal file
52
util/stdlib/strlcpy.h
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_UTIL_STDLIB_STRLCPY_H_
|
||||
#define CRASHPAD_UTIL_STDLIB_STRLCPY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief Copy a `NUL`-terminated char16-based string to a fixed-size buffer.
|
||||
//!
|
||||
//! This function behaves identically to `strlcpy()`, but it operates on char16
|
||||
//! data instead of `char` data. It copies the `NUL`-terminated string in the
|
||||
//! buffer beginning at \a source to the buffer of size \a length at \a
|
||||
//! destination, ensuring that the destination buffer is `NUL`-terminated. No
|
||||
//! data will be written outside of the \a destination buffer, but if \a length
|
||||
//! is smaller than the length of the string at \a source, the string will be
|
||||
//! truncated.
|
||||
//!
|
||||
//! \param[out] destination A pointer to a buffer of at least size \a length
|
||||
//! char16 units (not bytes). The string will be copied to this buffer,
|
||||
//! possibly with truncation, and `NUL`-terminated. Nothing will be written
|
||||
//! following the `NUL` terminator.
|
||||
//! \param[in] source A pointer to a `NUL`-terminated string of char16 data. The
|
||||
//! `NUL` terminator must be a `NUL` value in a char16 unit, not just a
|
||||
//! single `NUL` byte.
|
||||
//! \param[in] length The length of the \a destination buffer in char16 units,
|
||||
//! not bytes. A maximum of \a `length - 1` char16 units from \a source will
|
||||
//! be copied to \a destination.
|
||||
//!
|
||||
//! \return The length of the \a source string in char16 units, not including
|
||||
//! its `NUL` terminator. When truncation occurs, the return value will be
|
||||
//! equal to or greater than than the \a length parameter.
|
||||
size_t c16lcpy(char16* destination, const char16* source, size_t length);
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_UTIL_STDLIB_STRLCPY_H_
|
90
util/stdlib/strlcpy_test.cc
Normal file
90
util/stdlib/strlcpy_test.cc
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/stdlib/strlcpy.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace crashpad;
|
||||
|
||||
TEST(strlcpy, c16lcpy) {
|
||||
// Use a destination buffer that’s larger than the length passed to c16lcpy.
|
||||
// The unused portion is a guard area that must not be written to.
|
||||
struct TestBuffer {
|
||||
char16 lead_guard[64];
|
||||
char16 data[128];
|
||||
char16 trail_guard[64];
|
||||
};
|
||||
TestBuffer expected_untouched;
|
||||
memset(&expected_untouched, 0xa5, sizeof(expected_untouched));
|
||||
|
||||
// Test with M, é, Ā, ő, and Ḙ. This is a mix of characters that have zero and
|
||||
// nonzero low and high bytes.
|
||||
const char16 test_characters[] = {0x4d, 0xe9, 0x100, 0x151, 0x1e18};
|
||||
|
||||
for (size_t index = 0; index < arraysize(test_characters); ++index) {
|
||||
char16 test_character = test_characters[index];
|
||||
SCOPED_TRACE(base::StringPrintf(
|
||||
"character index %zu, character 0x%x", index, test_character));
|
||||
for (size_t length = 0; length < 256; ++length) {
|
||||
SCOPED_TRACE(base::StringPrintf("index %zu", length));
|
||||
string16 test_string(length, test_character);
|
||||
|
||||
TestBuffer destination;
|
||||
memset(&destination, 0xa5, sizeof(destination));
|
||||
|
||||
EXPECT_EQ(length,
|
||||
c16lcpy(destination.data,
|
||||
test_string.c_str(),
|
||||
arraysize(destination.data)));
|
||||
|
||||
// Make sure that the destination buffer is NUL-terminated, and that as
|
||||
// much of the test string was copied as could fit.
|
||||
size_t expected_destination_length =
|
||||
std::min(length, arraysize(destination.data) - 1);
|
||||
|
||||
EXPECT_EQ('\0', destination.data[expected_destination_length]);
|
||||
EXPECT_EQ(expected_destination_length, base::c16len(destination.data));
|
||||
EXPECT_TRUE(base::c16memcmp(test_string.c_str(),
|
||||
destination.data,
|
||||
expected_destination_length) == 0);
|
||||
|
||||
// Make sure that the portion of the destination buffer that was not used
|
||||
// was not touched. This includes the guard areas and the unused portion
|
||||
// of the buffer passed to c16lcpy.
|
||||
EXPECT_TRUE(base::c16memcmp(expected_untouched.lead_guard,
|
||||
destination.lead_guard,
|
||||
arraysize(destination.lead_guard)) == 0);
|
||||
size_t expected_untouched_length =
|
||||
arraysize(destination.data) - expected_destination_length - 1;
|
||||
EXPECT_TRUE(
|
||||
base::c16memcmp(expected_untouched.data,
|
||||
&destination.data[expected_destination_length + 1],
|
||||
expected_untouched_length) == 0);
|
||||
EXPECT_TRUE(base::c16memcmp(expected_untouched.trail_guard,
|
||||
destination.trail_guard,
|
||||
arraysize(destination.trail_guard)) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
@ -32,6 +32,11 @@
|
||||
'file/file_writer.h',
|
||||
'file/string_file_writer.cc',
|
||||
'file/string_file_writer.h',
|
||||
'misc/uuid.cc',
|
||||
'misc/uuid.h',
|
||||
'stdlib/cxx.h',
|
||||
'stdlib/strlcpy.cc',
|
||||
'stdlib/strlcpy.h',
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -49,6 +54,8 @@
|
||||
'sources': [
|
||||
'../third_party/gtest/gtest/src/gtest_main.cc',
|
||||
'file/string_file_writer_test.cc',
|
||||
'misc/uuid_test.cc',
|
||||
'stdlib/strlcpy_test.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user