| Index: minidump/test/minidump_writable_test_util.cc
|
| diff --git a/minidump/test/minidump_writable_test_util.cc b/minidump/test/minidump_writable_test_util.cc
|
| index 7466d7cd191f948ffb5fb49d4956fad6c3b8f5e4..3e98a0335dadd3abe9ac94810833fc37dd79470e 100644
|
| --- a/minidump/test/minidump_writable_test_util.cc
|
| +++ b/minidump/test/minidump_writable_test_util.cc
|
| @@ -16,6 +16,7 @@
|
|
|
| #include <string>
|
|
|
| +#include "base/strings/string16.h"
|
| #include "gtest/gtest.h"
|
|
|
| namespace crashpad {
|
| @@ -34,12 +35,20 @@ const void* MinidumpWritableAtRVAInternal(const std::string& file_contents,
|
| const void* MinidumpWritableAtLocationDescriptorInternal(
|
| const std::string& file_contents,
|
| const MINIDUMP_LOCATION_DESCRIPTOR& location,
|
| - size_t expected_minimum_size) {
|
| + size_t expected_size,
|
| + bool allow_oversized_data) {
|
| if (location.DataSize == 0) {
|
| EXPECT_EQ(0u, location.Rva);
|
| return nullptr;
|
| - } else if (location.DataSize < expected_minimum_size) {
|
| - EXPECT_GE(location.DataSize, expected_minimum_size);
|
| + }
|
| +
|
| + if (allow_oversized_data) {
|
| + if (location.DataSize < expected_size) {
|
| + EXPECT_GE(location.DataSize, expected_size);
|
| + return nullptr;
|
| + }
|
| + } else if (location.DataSize != expected_size) {
|
| + EXPECT_EQ(expected_size, location.DataSize);
|
| return nullptr;
|
| }
|
|
|
| @@ -54,5 +63,213 @@ const void* MinidumpWritableAtLocationDescriptorInternal(
|
| return rv;
|
| }
|
|
|
| +template <>
|
| +const IMAGE_DEBUG_MISC* MinidumpWritableAtLocationDescriptor<IMAGE_DEBUG_MISC>(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + const IMAGE_DEBUG_MISC* misc =
|
| + TMinidumpWritableAtLocationDescriptor<IMAGE_DEBUG_MISC>(file_contents,
|
| + location);
|
| + if (!misc) {
|
| + return nullptr;
|
| + }
|
| +
|
| + if (misc->DataType != IMAGE_DEBUG_MISC_EXENAME) {
|
| + EXPECT_EQ(static_cast<uint32_t>(IMAGE_DEBUG_MISC_EXENAME), misc->DataType);
|
| + return nullptr;
|
| + }
|
| +
|
| + if (misc->Length != location.DataSize) {
|
| + EXPECT_EQ(location.DataSize, misc->Length);
|
| + return nullptr;
|
| + }
|
| +
|
| + if (misc->Unicode == 0) {
|
| + size_t string_length = misc->Length - offsetof(IMAGE_DEBUG_MISC, Data) - 1;
|
| + if (misc->Data[string_length] != '\0') {
|
| + EXPECT_EQ('\0', misc->Data[string_length]);
|
| + return nullptr;
|
| + }
|
| + } else if (misc->Unicode == 1) {
|
| + if (misc->Length % sizeof(char16) != 0) {
|
| + EXPECT_EQ(0u, misc->Length % sizeof(char16));
|
| + return nullptr;
|
| + }
|
| +
|
| + size_t string_length =
|
| + (misc->Length - offsetof(IMAGE_DEBUG_MISC, Data)) / sizeof(char16) - 1;
|
| + const char16* data16 = reinterpret_cast<const char16*>(misc->Data);
|
| + if (data16[string_length] != '\0') {
|
| + EXPECT_EQ('\0', data16[string_length]);
|
| + return nullptr;
|
| + }
|
| + } else {
|
| + ADD_FAILURE() << "misc->Unicode " << misc->Unicode;
|
| + return nullptr;
|
| + }
|
| +
|
| + return misc;
|
| +}
|
| +
|
| +template <>
|
| +const MINIDUMP_HEADER* MinidumpWritableAtLocationDescriptor<MINIDUMP_HEADER>(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + const MINIDUMP_HEADER* header =
|
| + TMinidumpWritableAtLocationDescriptor<MINIDUMP_HEADER>(file_contents,
|
| + location);
|
| + if (!header) {
|
| + return nullptr;
|
| + }
|
| +
|
| + if (header->Signature != MINIDUMP_SIGNATURE) {
|
| + EXPECT_EQ(static_cast<uint32_t>(MINIDUMP_SIGNATURE), header->Signature);
|
| + return nullptr;
|
| + }
|
| + if (header->Version != MINIDUMP_VERSION) {
|
| + EXPECT_EQ(static_cast<uint32_t>(MINIDUMP_VERSION), header->Version);
|
| + return nullptr;
|
| + }
|
| +
|
| + return header;
|
| +}
|
| +
|
| +namespace {
|
| +
|
| +struct MinidumpMemoryListTraits {
|
| + typedef MINIDUMP_MEMORY_LIST ListType;
|
| + static constexpr size_t kElementSize = sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
|
| + static size_t ElementCount(const ListType* list) {
|
| + return list->NumberOfMemoryRanges;
|
| + }
|
| +};
|
| +
|
| +struct MinidumpModuleListTraits {
|
| + typedef MINIDUMP_MODULE_LIST ListType;
|
| + static constexpr size_t kElementSize = sizeof(MINIDUMP_MODULE);
|
| + static size_t ElementCount(const ListType* list) {
|
| + return list->NumberOfModules;
|
| + }
|
| +};
|
| +
|
| +struct MinidumpThreadListTraits {
|
| + typedef MINIDUMP_THREAD_LIST ListType;
|
| + static constexpr size_t kElementSize = sizeof(MINIDUMP_THREAD);
|
| + static size_t ElementCount(const ListType* list) {
|
| + return list->NumberOfThreads;
|
| + }
|
| +};
|
| +
|
| +struct MinidumpSimpleStringDictionaryListTraits {
|
| + typedef MinidumpSimpleStringDictionary ListType;
|
| + static constexpr size_t kElementSize =
|
| + sizeof(MinidumpSimpleStringDictionaryEntry);
|
| + static size_t ElementCount(const ListType* list) {
|
| + return list->count;
|
| + }
|
| +};
|
| +
|
| +template <typename T>
|
| +const typename T::ListType* MinidumpListAtLocationDescriptor(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + const typename T::ListType* list =
|
| + TMinidumpWritableAtLocationDescriptor<typename T::ListType>(file_contents,
|
| + location);
|
| + if (!list) {
|
| + return nullptr;
|
| + }
|
| +
|
| + size_t expected_size =
|
| + sizeof(typename T::ListType) + T::ElementCount(list) * T::kElementSize;
|
| + if (location.DataSize != expected_size) {
|
| + EXPECT_EQ(expected_size, location.DataSize);
|
| + return nullptr;
|
| + }
|
| +
|
| + return list;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +template <>
|
| +const MINIDUMP_MEMORY_LIST* MinidumpWritableAtLocationDescriptor<
|
| + MINIDUMP_MEMORY_LIST>(const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + return MinidumpListAtLocationDescriptor<MinidumpMemoryListTraits>(
|
| + file_contents, location);
|
| +}
|
| +
|
| +template <>
|
| +const MINIDUMP_MODULE_LIST* MinidumpWritableAtLocationDescriptor<
|
| + MINIDUMP_MODULE_LIST>(const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + return MinidumpListAtLocationDescriptor<MinidumpModuleListTraits>(
|
| + file_contents, location);
|
| +}
|
| +
|
| +template <>
|
| +const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
|
| + MINIDUMP_THREAD_LIST>(const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + return MinidumpListAtLocationDescriptor<MinidumpThreadListTraits>(
|
| + file_contents, location);
|
| +}
|
| +
|
| +template <>
|
| +const MinidumpSimpleStringDictionary*
|
| +MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + return MinidumpListAtLocationDescriptor<
|
| + MinidumpSimpleStringDictionaryListTraits>(file_contents, location);
|
| +}
|
| +
|
| +namespace {
|
| +
|
| +template <typename T>
|
| +const T* MinidumpCVPDBAtLocationDescriptor(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + const T* cv_pdb =
|
| + TMinidumpWritableAtLocationDescriptor<T>(file_contents, location);
|
| + if (!cv_pdb) {
|
| + return nullptr;
|
| + }
|
| +
|
| + if (cv_pdb->signature != T::kSignature) {
|
| + EXPECT_EQ(T::kSignature, cv_pdb->signature);
|
| + return nullptr;
|
| + }
|
| +
|
| + size_t string_length = location.DataSize - offsetof(T, pdb_name) - 1;
|
| + if (cv_pdb->pdb_name[string_length] != '\0') {
|
| + EXPECT_EQ('\0', cv_pdb->pdb_name[string_length]);
|
| + return nullptr;
|
| + }
|
| +
|
| + return cv_pdb;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +template <>
|
| +const MinidumpModuleCodeViewRecordPDB20*
|
| +MinidumpWritableAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB20>(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + return MinidumpCVPDBAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB20>(
|
| + file_contents, location);
|
| +}
|
| +
|
| +template <>
|
| +const MinidumpModuleCodeViewRecordPDB70*
|
| +MinidumpWritableAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB70>(
|
| + const std::string& file_contents,
|
| + const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
| + return MinidumpCVPDBAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB70>(
|
| + file_contents, location);
|
| +}
|
| +
|
| } // namespace test
|
| } // namespace crashpad
|
|
|