Chromium Code Reviews| 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..65845eb967af7572e78eca0c43becb8608a9b44c 100644 |
| --- a/minidump/test/minidump_writable_test_util.cc |
| +++ b/minidump/test/minidump_writable_test_util.cc |
| @@ -34,12 +34,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 +62,211 @@ 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 % 2 != 0) { |
|
Robert Sesek
2014/10/22 21:57:52
Would be helpful to have a comment that Unicode in
|
| + EXPECT_EQ(0u, misc->Length % 2); |
| + return nullptr; |
| + } |
| + |
| + size_t string_length = |
| + (misc->Length - offsetof(IMAGE_DEBUG_MISC, Data)) / 2 - 1; |
| + const uint16_t* data16 = reinterpret_cast<const uint16_t*>(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; } |
|
Robert Sesek
2014/10/22 21:57:52
nit: This is the only impl that you onelined.
|
| +}; |
| + |
| +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 |