Refactor minidump test utilities for MinidumpWritable,
MinidumpFileWriter, and Minidump*StringWriter. TEST=minidump_test R=rsesek@chromium.org Review URL: https://codereview.chromium.org/664283002
This commit is contained in:
Родитель
01c535b001
Коммит
8a6a4c68e4
|
@ -95,6 +95,8 @@
|
|||
'test/minidump_memory_writer_test_util.h',
|
||||
'test/minidump_string_writer_test_util.cc',
|
||||
'test/minidump_string_writer_test_util.h',
|
||||
'test/minidump_writable_test_util.cc',
|
||||
'test/minidump_writable_test_util.h',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -48,18 +48,15 @@ void GetCrashpadInfoStream(
|
|||
EXPECT_GE(file_contents.size(), kFileSize);
|
||||
}
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeCrashpadInfo, directory->StreamType);
|
||||
ASSERT_EQ(sizeof(MinidumpCrashpadInfo), directory->Location.DataSize);
|
||||
ASSERT_EQ(kCrashpadInfoStreamOffset, directory->Location.Rva);
|
||||
ASSERT_EQ(kMinidumpStreamTypeCrashpadInfo, directory[0].StreamType);
|
||||
ASSERT_EQ(sizeof(MinidumpCrashpadInfo), directory[0].Location.DataSize);
|
||||
ASSERT_EQ(kCrashpadInfoStreamOffset, directory[0].Location.Rva);
|
||||
|
||||
*crashpad_info = reinterpret_cast<const MinidumpCrashpadInfo*>(
|
||||
&file_contents[kCrashpadInfoStreamOffset]);
|
||||
|
@ -136,18 +133,18 @@ TEST(MinidumpCrashpadInfoWriter, SimpleAnnotations) {
|
|||
|
||||
ASSERT_EQ(2u, simple_annotations->count);
|
||||
|
||||
EXPECT_EQ(
|
||||
kKey1,
|
||||
MinidumpUTF8StringAtRVA(file_writer, simple_annotations->entries[0].key));
|
||||
EXPECT_EQ(kKey1,
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
file_writer.string(), simple_annotations->entries[0].key));
|
||||
EXPECT_EQ(kValue1,
|
||||
MinidumpUTF8StringAtRVA(file_writer,
|
||||
simple_annotations->entries[0].value));
|
||||
EXPECT_EQ(
|
||||
kKey0,
|
||||
MinidumpUTF8StringAtRVA(file_writer, simple_annotations->entries[1].key));
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
file_writer.string(), simple_annotations->entries[0].value));
|
||||
EXPECT_EQ(kKey0,
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
file_writer.string(), simple_annotations->entries[1].key));
|
||||
EXPECT_EQ(kValue0,
|
||||
MinidumpUTF8StringAtRVA(file_writer,
|
||||
simple_annotations->entries[1].value));
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
file_writer.string(), simple_annotations->entries[1].value));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -44,15 +44,11 @@ void GetExceptionStream(const std::string& file_contents,
|
|||
const size_t kFileSize = kContextOffset + sizeof(MinidumpContextX86);
|
||||
ASSERT_EQ(file_contents.size(), kFileSize);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeException, directory[0].StreamType);
|
||||
ASSERT_GE(directory[0].Location.DataSize, sizeof(MINIDUMP_EXCEPTION_STREAM));
|
||||
ASSERT_EQ(kExceptionStreamOffset, directory[0].Location.Rva);
|
||||
|
|
|
@ -36,10 +36,11 @@ TEST(MinidumpFileWriter, Empty) {
|
|||
ASSERT_TRUE(minidump_file.WriteEverything(&file_writer));
|
||||
ASSERT_EQ(sizeof(MINIDUMP_HEADER), file_writer.string().size());
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_writer.string()[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_writer.string(), &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 0, 0));
|
||||
EXPECT_FALSE(directory);
|
||||
}
|
||||
|
||||
class TestStream final : public internal::MinidumpStreamWriter {
|
||||
|
@ -95,18 +96,15 @@ TEST(MinidumpFileWriter, OneStream) {
|
|||
|
||||
ASSERT_EQ(kFileSize, file_writer.string().size());
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_writer.string()[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_writer.string(), &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, kTimestamp));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_writer.string()[kDirectoryOffset]);
|
||||
|
||||
EXPECT_EQ(kStreamType, directory->StreamType);
|
||||
EXPECT_EQ(kStreamSize, directory->Location.DataSize);
|
||||
EXPECT_EQ(kStreamOffset, directory->Location.Rva);
|
||||
EXPECT_EQ(kStreamType, directory[0].StreamType);
|
||||
EXPECT_EQ(kStreamSize, directory[0].Location.DataSize);
|
||||
EXPECT_EQ(kStreamOffset, directory[0].Location.Rva);
|
||||
|
||||
const uint8_t* stream_data =
|
||||
reinterpret_cast<const uint8_t*>(&file_writer.string()[kStreamOffset]);
|
||||
|
@ -155,14 +153,11 @@ TEST(MinidumpFileWriter, ThreeStreams) {
|
|||
|
||||
ASSERT_EQ(kFileSize, file_writer.string().size());
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_writer.string()[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_writer.string(), &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 3, kTimestamp));
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_writer.string()[kDirectoryOffset]);
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
EXPECT_EQ(kStream1Type, directory[0].StreamType);
|
||||
EXPECT_EQ(kStream1Size, directory[0].Location.DataSize);
|
||||
|
@ -217,18 +212,15 @@ TEST(MinidumpFileWriter, ZeroLengthStream) {
|
|||
|
||||
ASSERT_EQ(kFileSize, file_writer.string().size());
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_writer.string()[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_writer.string(), &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_writer.string()[kDirectoryOffset]);
|
||||
|
||||
EXPECT_EQ(kStreamType, directory->StreamType);
|
||||
EXPECT_EQ(kStreamSize, directory->Location.DataSize);
|
||||
EXPECT_EQ(kStreamOffset, directory->Location.Rva);
|
||||
EXPECT_EQ(kStreamType, directory[0].StreamType);
|
||||
EXPECT_EQ(kStreamSize, directory[0].Location.DataSize);
|
||||
EXPECT_EQ(kStreamOffset, directory[0].Location.Rva);
|
||||
}
|
||||
|
||||
TEST(MinidumpFileWriterDeathTest, SameStreamType) {
|
||||
|
|
|
@ -47,25 +47,25 @@ void GetMemoryListStream(const std::string& file_contents,
|
|||
|
||||
ASSERT_GE(file_contents.size(), kMemoryDescriptorsOffset);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, expected_streams, 0));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
size_t directory_index = 0;
|
||||
if (expected_streams > 1) {
|
||||
ASSERT_EQ(kBogusStreamType, directory->StreamType);
|
||||
ASSERT_EQ(0u, directory->Location.DataSize);
|
||||
ASSERT_EQ(kMemoryListStreamOffset, directory->Location.Rva);
|
||||
++directory;
|
||||
ASSERT_EQ(kBogusStreamType, directory[directory_index].StreamType);
|
||||
ASSERT_EQ(0u, directory[directory_index].Location.DataSize);
|
||||
ASSERT_EQ(kMemoryListStreamOffset, directory[directory_index].Location.Rva);
|
||||
++directory_index;
|
||||
}
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeMemoryList, directory->StreamType);
|
||||
ASSERT_GE(directory->Location.DataSize, sizeof(MINIDUMP_MEMORY_LIST));
|
||||
ASSERT_EQ(kMemoryListStreamOffset, directory->Location.Rva);
|
||||
ASSERT_EQ(kMinidumpStreamTypeMemoryList,
|
||||
directory[directory_index].StreamType);
|
||||
ASSERT_GE(directory[directory_index].Location.DataSize,
|
||||
sizeof(MINIDUMP_MEMORY_LIST));
|
||||
ASSERT_EQ(kMemoryListStreamOffset, directory[directory_index].Location.Rva);
|
||||
|
||||
*memory_list = reinterpret_cast<const MINIDUMP_MEMORY_LIST*>(
|
||||
&file_contents[kMemoryListStreamOffset]);
|
||||
|
@ -73,7 +73,7 @@ void GetMemoryListStream(const std::string& file_contents,
|
|||
ASSERT_EQ(sizeof(MINIDUMP_MEMORY_LIST) +
|
||||
(*memory_list)->NumberOfMemoryRanges *
|
||||
sizeof(MINIDUMP_MEMORY_DESCRIPTOR),
|
||||
directory->Location.DataSize);
|
||||
directory[directory_index].Location.DataSize);
|
||||
}
|
||||
|
||||
TEST(MinidumpMemoryWriter, EmptyMemoryList) {
|
||||
|
|
|
@ -42,18 +42,15 @@ void GetMiscInfoStream(const std::string& file_contents, const T** misc_info) {
|
|||
|
||||
ASSERT_EQ(kFileSize, file_contents.size());
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeMiscInfo, directory->StreamType);
|
||||
ASSERT_EQ(kMiscInfoStreamSize, directory->Location.DataSize);
|
||||
ASSERT_EQ(kMiscInfoStreamOffset, directory->Location.Rva);
|
||||
ASSERT_EQ(kMinidumpStreamTypeMiscInfo, directory[0].StreamType);
|
||||
ASSERT_EQ(kMiscInfoStreamSize, directory[0].Location.DataSize);
|
||||
ASSERT_EQ(kMiscInfoStreamOffset, directory[0].Location.Rva);
|
||||
|
||||
*misc_info =
|
||||
reinterpret_cast<const T*>(&file_contents[kMiscInfoStreamOffset]);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||
#include "minidump/test/minidump_string_writer_test_util.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
#include "util/misc/uuid.h"
|
||||
|
||||
|
@ -40,25 +41,22 @@ void GetModuleListStream(const std::string& file_contents,
|
|||
|
||||
ASSERT_GE(file_contents.size(), kModulesOffset);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeModuleList, directory->StreamType);
|
||||
ASSERT_GE(directory->Location.DataSize, sizeof(MINIDUMP_MODULE_LIST));
|
||||
ASSERT_EQ(kModuleListStreamOffset, directory->Location.Rva);
|
||||
ASSERT_EQ(kMinidumpStreamTypeModuleList, directory[0].StreamType);
|
||||
ASSERT_GE(directory[0].Location.DataSize, sizeof(MINIDUMP_MODULE_LIST));
|
||||
ASSERT_EQ(kModuleListStreamOffset, directory[0].Location.Rva);
|
||||
|
||||
*module_list = reinterpret_cast<const MINIDUMP_MODULE_LIST*>(
|
||||
&file_contents[kModuleListStreamOffset]);
|
||||
|
||||
ASSERT_EQ(sizeof(MINIDUMP_MODULE_LIST) +
|
||||
(*module_list)->NumberOfModules * sizeof(MINIDUMP_MODULE),
|
||||
directory->Location.DataSize);
|
||||
directory[0].Location.DataSize);
|
||||
}
|
||||
|
||||
TEST(MinidumpModuleWriter, EmptyModuleList) {
|
||||
|
@ -256,18 +254,8 @@ void ExpectModule(const MINIDUMP_MODULE* expected,
|
|||
EXPECT_EQ(0u, observed->Reserved1);
|
||||
|
||||
EXPECT_NE(0u, observed->ModuleNameRva);
|
||||
ASSERT_LE(observed->ModuleNameRva,
|
||||
file_contents.size() - sizeof(MINIDUMP_STRING));
|
||||
const MINIDUMP_STRING* module_name = reinterpret_cast<const MINIDUMP_STRING*>(
|
||||
&file_contents[observed->ModuleNameRva]);
|
||||
ASSERT_LE(observed->ModuleNameRva + sizeof(MINIDUMP_STRING) +
|
||||
(module_name->Length + 1),
|
||||
file_contents.size());
|
||||
ASSERT_EQ(0u, module_name->Length % 2);
|
||||
string16 observed_module_name_utf16(
|
||||
reinterpret_cast<const char16*>(
|
||||
&file_contents[observed->ModuleNameRva + sizeof(MINIDUMP_STRING)]),
|
||||
module_name->Length / 2);
|
||||
string16 observed_module_name_utf16 =
|
||||
MinidumpStringAtRVAAsString(file_contents, observed->ModuleNameRva);
|
||||
string16 expected_module_name_utf16 = base::UTF8ToUTF16(expected_module_name);
|
||||
EXPECT_EQ(expected_module_name_utf16, observed_module_name_utf16);
|
||||
|
||||
|
|
|
@ -64,9 +64,11 @@ TEST(MinidumpSimpleStringDictionaryWriter, EmptyKeyValue) {
|
|||
EXPECT_EQ(12u, dictionary->entries[0].key);
|
||||
EXPECT_EQ(20u, dictionary->entries[0].value);
|
||||
EXPECT_EQ("",
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].key));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].key));
|
||||
EXPECT_EQ("",
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].value));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].value));
|
||||
}
|
||||
|
||||
TEST(MinidumpSimpleStringDictionaryWriter, OneKeyValue) {
|
||||
|
@ -92,9 +94,11 @@ TEST(MinidumpSimpleStringDictionaryWriter, OneKeyValue) {
|
|||
EXPECT_EQ(12u, dictionary->entries[0].key);
|
||||
EXPECT_EQ(20u, dictionary->entries[0].value);
|
||||
EXPECT_EQ(kKey,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].key));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].key));
|
||||
EXPECT_EQ(kValue,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].value));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].value));
|
||||
}
|
||||
|
||||
TEST(MinidumpSimpleStringDictionaryWriter, ThreeKeysValues) {
|
||||
|
@ -143,17 +147,23 @@ TEST(MinidumpSimpleStringDictionaryWriter, ThreeKeysValues) {
|
|||
// just the easiest way to write this test while the writer will output things
|
||||
// in a known order.
|
||||
EXPECT_EQ(kKey2,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].key));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].key));
|
||||
EXPECT_EQ(kValue2,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].value));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].value));
|
||||
EXPECT_EQ(kKey0,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[1].key));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[1].key));
|
||||
EXPECT_EQ(kValue0,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[1].value));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[1].value));
|
||||
EXPECT_EQ(kKey1,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[2].key));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[2].key));
|
||||
EXPECT_EQ(kValue1,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[2].value));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[2].value));
|
||||
}
|
||||
|
||||
TEST(MinidumpSimpleStringDictionaryWriter, DuplicateKeyValue) {
|
||||
|
@ -183,9 +193,11 @@ TEST(MinidumpSimpleStringDictionaryWriter, DuplicateKeyValue) {
|
|||
EXPECT_EQ(12u, dictionary->entries[0].key);
|
||||
EXPECT_EQ(20u, dictionary->entries[0].value);
|
||||
EXPECT_EQ(kKey,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].key));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].key));
|
||||
EXPECT_EQ(kValue1,
|
||||
MinidumpUTF8StringAtRVA(file_writer, dictionary->entries[0].value));
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
|
||||
dictionary->entries[0].value));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -22,16 +22,13 @@
|
|||
#include "base/strings/string16.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/test/minidump_string_writer_test_util.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
const MINIDUMP_STRING* MinidumpStringCast(const StringFileWriter& file_writer) {
|
||||
return reinterpret_cast<const MINIDUMP_STRING*>(&file_writer.string()[0]);
|
||||
}
|
||||
|
||||
TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) {
|
||||
StringFileWriter file_writer;
|
||||
|
||||
|
@ -41,9 +38,11 @@ TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) {
|
|||
crashpad::internal::MinidumpUTF16StringWriter string_writer;
|
||||
EXPECT_TRUE(string_writer.WriteEverything(&file_writer));
|
||||
ASSERT_EQ(6u, file_writer.string().size());
|
||||
const MINIDUMP_STRING* minidump_string = MinidumpStringCast(file_writer);
|
||||
EXPECT_EQ(0u, minidump_string->Length);
|
||||
EXPECT_EQ(0, minidump_string->Buffer[0]);
|
||||
|
||||
const MINIDUMP_STRING* minidump_string =
|
||||
MinidumpStringAtRVA(file_writer.string(), 0);
|
||||
EXPECT_TRUE(minidump_string);
|
||||
EXPECT_EQ(string16(), MinidumpStringAtRVAAsString(file_writer.string(), 0));
|
||||
}
|
||||
|
||||
const struct {
|
||||
|
@ -88,14 +87,14 @@ TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) {
|
|||
expected_utf16_units_with_nul * sizeof(MINIDUMP_STRING::Buffer[0]);
|
||||
ASSERT_EQ(sizeof(MINIDUMP_STRING) + expected_utf16_bytes,
|
||||
file_writer.string().size());
|
||||
const MINIDUMP_STRING* minidump_string = MinidumpStringCast(file_writer);
|
||||
EXPECT_EQ(
|
||||
kTestData[index].output_length * sizeof(minidump_string->Buffer[0]),
|
||||
minidump_string->Length);
|
||||
EXPECT_EQ(0,
|
||||
base::c16memcmp(kTestData[index].output_string,
|
||||
minidump_string->Buffer,
|
||||
expected_utf16_units_with_nul));
|
||||
|
||||
const MINIDUMP_STRING* minidump_string =
|
||||
MinidumpStringAtRVA(file_writer.string(), 0);
|
||||
EXPECT_TRUE(minidump_string);
|
||||
string16 expect_string = string16(kTestData[index].output_string,
|
||||
kTestData[index].output_length);
|
||||
EXPECT_EQ(expect_string,
|
||||
MinidumpStringAtRVAAsString(file_writer.string(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,27 +121,21 @@ TEST(MinidumpStringWriter, ConvertInvalidUTF8ToUTF16) {
|
|||
// The requirements for conversion of invalid UTF-8 input are lax. Make sure
|
||||
// that at least enough data was written for a string that has one unit and
|
||||
// a NUL terminator, make sure that the length field matches the length of
|
||||
// data written, make sure the data is NUL-terminated, and make sure that at
|
||||
// least one U+FFFD replacement character was written.
|
||||
ASSERT_GE(file_writer.string().size(),
|
||||
sizeof(MINIDUMP_STRING) + 2 * sizeof(MINIDUMP_STRING::Buffer[0]));
|
||||
const MINIDUMP_STRING* minidump_string = MinidumpStringCast(file_writer);
|
||||
// data written, and make sure that at least one U+FFFD replacement
|
||||
// character was written.
|
||||
const MINIDUMP_STRING* minidump_string =
|
||||
MinidumpStringAtRVA(file_writer.string(), 0);
|
||||
EXPECT_TRUE(minidump_string);
|
||||
EXPECT_EQ(file_writer.string().size() - sizeof(MINIDUMP_STRING) -
|
||||
sizeof(MINIDUMP_STRING::Buffer[0]),
|
||||
minidump_string->Length);
|
||||
size_t out_units =
|
||||
minidump_string->Length / sizeof(minidump_string->Buffer[0]);
|
||||
EXPECT_EQ(0, minidump_string->Buffer[out_units]);
|
||||
EXPECT_NE(nullptr,
|
||||
base::c16memchr(minidump_string->Buffer, 0xfffd, out_units));
|
||||
string16 output_string =
|
||||
MinidumpStringAtRVAAsString(file_writer.string(), 0);
|
||||
EXPECT_FALSE(output_string.empty());
|
||||
EXPECT_NE(string16::npos, output_string.find(0xfffd));
|
||||
}
|
||||
}
|
||||
|
||||
const MinidumpUTF8String* MinidumpUTF8StringCast(
|
||||
const StringFileWriter& file_writer) {
|
||||
return reinterpret_cast<const MinidumpUTF8String*>(&file_writer.string()[0]);
|
||||
}
|
||||
|
||||
TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) {
|
||||
StringFileWriter file_writer;
|
||||
|
||||
|
@ -152,10 +145,12 @@ TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) {
|
|||
crashpad::internal::MinidumpUTF8StringWriter string_writer;
|
||||
EXPECT_TRUE(string_writer.WriteEverything(&file_writer));
|
||||
ASSERT_EQ(5u, file_writer.string().size());
|
||||
|
||||
const MinidumpUTF8String* minidump_string =
|
||||
MinidumpUTF8StringCast(file_writer);
|
||||
EXPECT_EQ(0u, minidump_string->Length);
|
||||
EXPECT_EQ(0, minidump_string->Buffer[0]);
|
||||
MinidumpUTF8StringAtRVA(file_writer.string(), 0);
|
||||
EXPECT_TRUE(minidump_string);
|
||||
EXPECT_EQ(std::string(),
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(), 0));
|
||||
}
|
||||
|
||||
const struct {
|
||||
|
@ -189,13 +184,12 @@ TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) {
|
|||
const size_t expected_utf8_bytes_with_nul = kTestData[index].length + 1;
|
||||
ASSERT_EQ(sizeof(MinidumpUTF8String) + expected_utf8_bytes_with_nul,
|
||||
file_writer.string().size());
|
||||
|
||||
const MinidumpUTF8String* minidump_string =
|
||||
MinidumpUTF8StringCast(file_writer);
|
||||
EXPECT_EQ(kTestData[index].length, minidump_string->Length);
|
||||
EXPECT_EQ(0,
|
||||
memcmp(kTestData[index].string,
|
||||
minidump_string->Buffer,
|
||||
expected_utf8_bytes_with_nul));
|
||||
MinidumpUTF8StringAtRVA(file_writer.string(), 0);
|
||||
EXPECT_TRUE(minidump_string);
|
||||
EXPECT_EQ(test_string,
|
||||
MinidumpUTF8StringAtRVAAsString(file_writer.string(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||
#include "minidump/test/minidump_string_writer_test_util.h"
|
||||
#include "util/file/string_file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
@ -48,27 +49,23 @@ void GetSystemInfoStream(const std::string& file_contents,
|
|||
|
||||
ASSERT_EQ(kFileSize, file_contents.size());
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeSystemInfo, directory->StreamType);
|
||||
ASSERT_EQ(sizeof(MINIDUMP_SYSTEM_INFO), directory->Location.DataSize);
|
||||
ASSERT_EQ(kSystemInfoStreamOffset, directory->Location.Rva);
|
||||
ASSERT_EQ(kMinidumpStreamTypeSystemInfo, directory[0].StreamType);
|
||||
ASSERT_EQ(sizeof(MINIDUMP_SYSTEM_INFO), directory[0].Location.DataSize);
|
||||
ASSERT_EQ(kSystemInfoStreamOffset, directory[0].Location.Rva);
|
||||
|
||||
*system_info = reinterpret_cast<const MINIDUMP_SYSTEM_INFO*>(
|
||||
&file_contents[kSystemInfoStreamOffset]);
|
||||
|
||||
ASSERT_EQ(kCSDVersionOffset, (*system_info)->CSDVersionRva);
|
||||
|
||||
*csd_version = reinterpret_cast<const MINIDUMP_STRING*>(
|
||||
&file_contents[kCSDVersionOffset]);
|
||||
|
||||
*csd_version =
|
||||
MinidumpStringAtRVA(file_contents, (*system_info)->CSDVersionRva);
|
||||
ASSERT_EQ(kCSDVersionBytes, (*csd_version)->Length);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,14 +44,11 @@ void GetThreadListStream(const std::string& file_contents,
|
|||
|
||||
ASSERT_GE(file_contents.size(), kThreadsOffset);
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory;
|
||||
const MINIDUMP_HEADER* header =
|
||||
reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
|
||||
|
||||
MinidumpHeaderAtStart(file_contents, &directory);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, kExpectedStreams, 0));
|
||||
|
||||
const MINIDUMP_DIRECTORY* directory =
|
||||
reinterpret_cast<const MINIDUMP_DIRECTORY*>(
|
||||
&file_contents[kDirectoryOffset]);
|
||||
ASSERT_TRUE(directory);
|
||||
|
||||
ASSERT_EQ(kMinidumpStreamTypeThreadList, directory[0].StreamType);
|
||||
ASSERT_GE(directory[0].Location.DataSize, sizeof(MINIDUMP_THREAD_LIST));
|
||||
|
|
|
@ -15,13 +15,48 @@
|
|||
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
const MINIDUMP_HEADER* MinidumpHeaderAtStart(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_DIRECTORY** directory) {
|
||||
MINIDUMP_LOCATION_DESCRIPTOR location_descriptor;
|
||||
location_descriptor.DataSize = sizeof(MINIDUMP_HEADER);
|
||||
location_descriptor.Rva = 0;
|
||||
|
||||
const MINIDUMP_HEADER* header =
|
||||
MinidumpWritableAtLocationDescriptor<MINIDUMP_HEADER>(
|
||||
file_contents, location_descriptor);
|
||||
|
||||
if (header) {
|
||||
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;
|
||||
}
|
||||
|
||||
location_descriptor.DataSize =
|
||||
header->NumberOfStreams * sizeof(MINIDUMP_DIRECTORY);
|
||||
location_descriptor.Rva = header->StreamDirectoryRva;
|
||||
*directory = MinidumpWritableAtLocationDescriptor<MINIDUMP_DIRECTORY>(
|
||||
file_contents, location_descriptor);
|
||||
} else {
|
||||
*directory = nullptr;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
void VerifyMinidumpHeader(const MINIDUMP_HEADER* header,
|
||||
uint32_t streams,
|
||||
uint32_t timestamp) {
|
||||
ASSERT_TRUE(header);
|
||||
EXPECT_EQ(static_cast<uint32_t>(MINIDUMP_SIGNATURE), header->Signature);
|
||||
EXPECT_EQ(static_cast<uint32_t>(MINIDUMP_VERSION), header->Version);
|
||||
ASSERT_EQ(streams, header->NumberOfStreams);
|
||||
|
|
|
@ -18,9 +18,30 @@
|
|||
#include <dbghelp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
//! \brief Returns the MINIDUMP_HEADER at the start of a minidump file, along
|
||||
//! with the MINIDUMP_DIRECTORY it references.
|
||||
//!
|
||||
//! This function validates the MINIDUMP_HEADER::Signature and
|
||||
//! MINIDUMP_HEADER::Version fields.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[out] directory The MINIDUMP_DIRECTORY referenced by the
|
||||
//! MINIDUMP_HEADER. If the MINIDUMP_HEADER does not reference a
|
||||
//! MINIDUMP_DIRECTORY, `nullptr` without raising a gtest assertion. If the
|
||||
//! referenced MINIDUMP_DIRECTORY is not valid, `nullptr` with a gtest
|
||||
//! assertion raised. On failure, `nullptr`.
|
||||
//!
|
||||
//! \return On success, the MINIDUMP_HEADER at the beginning of the minidump
|
||||
//! file. On failure, raises a gtest assertion and returns `nullptr`.
|
||||
const MINIDUMP_HEADER* MinidumpHeaderAtStart(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_DIRECTORY** directory);
|
||||
|
||||
//! \brief Verifies, via gtest assertions, that a MINIDUMP_HEADER contains
|
||||
//! expected values.
|
||||
//!
|
||||
|
|
|
@ -16,41 +16,90 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
std::string MinidumpUTF8StringAtRVA(const StringFileWriter& file_writer,
|
||||
RVA rva) {
|
||||
const std::string& contents = file_writer.string();
|
||||
if (rva == 0) {
|
||||
return std::string();
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
const T* TMinidumpStringAtRVA(const std::string& file_contents, RVA rva) {
|
||||
const T* string_base = MinidumpWritableAtRVA<T>(file_contents, rva);
|
||||
if (!string_base) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (rva + sizeof(MinidumpUTF8String) > contents.size()) {
|
||||
ADD_FAILURE()
|
||||
<< "rva " << rva << " too large for contents " << contents.size();
|
||||
return std::string();
|
||||
// |Length| must indicate the ability to store an integral number of code
|
||||
// units.
|
||||
const size_t kCodeUnitSize = sizeof(string_base->Buffer[0]);
|
||||
if (string_base->Length % kCodeUnitSize != 0) {
|
||||
EXPECT_EQ(0u, string_base->Length % kCodeUnitSize);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MinidumpUTF8String* minidump_string =
|
||||
reinterpret_cast<const MinidumpUTF8String*>(&contents[rva]);
|
||||
|
||||
// Verify that the file has enough data for the string’s stated length plus
|
||||
// its required NUL terminator.
|
||||
if (rva + sizeof(MinidumpUTF8String) + minidump_string->Length + 1 >
|
||||
contents.size()) {
|
||||
ADD_FAILURE()
|
||||
<< "rva " << rva << ", length " << minidump_string->Length
|
||||
<< " too large for contents " << contents.size();
|
||||
return std::string();
|
||||
// |Length| does not include space for the required NUL terminator.
|
||||
MINIDUMP_LOCATION_DESCRIPTOR location;
|
||||
location.DataSize =
|
||||
sizeof(*string_base) + string_base->Length + kCodeUnitSize;
|
||||
location.Rva = rva;
|
||||
const T* string =
|
||||
MinidumpWritableAtLocationDescriptor<T>(file_contents, location);
|
||||
if (!string) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string minidump_string_data(
|
||||
reinterpret_cast<const char*>(&minidump_string->Buffer[0]),
|
||||
minidump_string->Length);
|
||||
EXPECT_EQ(string_base, string);
|
||||
|
||||
// Require the NUL terminator to be NUL.
|
||||
if (string->Buffer[string->Length / kCodeUnitSize] != '\0') {
|
||||
EXPECT_EQ('\0', string->Buffer[string->Length / kCodeUnitSize]);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
template <typename StringType, typename MinidumpStringType>
|
||||
StringType TMinidumpStringAtRVAAsString(const std::string& file_contents,
|
||||
RVA rva) {
|
||||
const MinidumpStringType* minidump_string =
|
||||
TMinidumpStringAtRVA<MinidumpStringType>(file_contents, rva);
|
||||
if (!minidump_string) {
|
||||
return StringType();
|
||||
}
|
||||
|
||||
StringType minidump_string_data(
|
||||
reinterpret_cast<const typename StringType::value_type*>(
|
||||
&minidump_string->Buffer[0]),
|
||||
minidump_string->Length / sizeof(minidump_string->Buffer[0]));
|
||||
return minidump_string_data;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const MINIDUMP_STRING* MinidumpStringAtRVA(const std::string& file_contents,
|
||||
RVA rva) {
|
||||
return TMinidumpStringAtRVA<MINIDUMP_STRING>(file_contents, rva);
|
||||
}
|
||||
|
||||
const MinidumpUTF8String* MinidumpUTF8StringAtRVA(
|
||||
const std::string& file_contents,
|
||||
RVA rva) {
|
||||
return TMinidumpStringAtRVA<MinidumpUTF8String>(file_contents, rva);
|
||||
}
|
||||
|
||||
string16 MinidumpStringAtRVAAsString(const std::string& file_contents,
|
||||
RVA rva) {
|
||||
return TMinidumpStringAtRVAAsString<string16, MINIDUMP_STRING>(file_contents,
|
||||
rva);
|
||||
}
|
||||
|
||||
std::string MinidumpUTF8StringAtRVAAsString(const std::string& file_contents,
|
||||
RVA rva) {
|
||||
return TMinidumpStringAtRVAAsString<std::string, MinidumpUTF8String>(
|
||||
file_contents, rva);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
|
|
@ -19,27 +19,82 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "util/file/string_file_writer.h"
|
||||
#include "base/strings/string16.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
struct MinidumpUTF8String;
|
||||
|
||||
namespace test {
|
||||
|
||||
//! \brief Returns the contents of a MinidumpUTF8String.
|
||||
//! \brief Returns a MINIDUMP_STRING located within a minidump file’s contents.
|
||||
//!
|
||||
//! If \a rva points outside of the range of \a file_writer, or if any of the
|
||||
//! string data would lie outside of the range of \a file_writer, this function
|
||||
//! will fail.
|
||||
//! If \a rva points outside of the range of \a file_contents, if the string has
|
||||
//! an incorrect length or is not `NUL`-terminated, or if any of the string data
|
||||
//! would lie outside of the range of \a file_contents, this function will fail.
|
||||
//!
|
||||
//! \param[in] file_writer A StringFileWriter into which MinidumpWritable
|
||||
//! objects have been written.
|
||||
//! \param[in] rva An offset in \a file_writer at which to find the desired
|
||||
//! string.
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset within the minidump file of the desired
|
||||
//! MINIDUMP_STRING.
|
||||
//!
|
||||
//! \return On success, a pointer to the MINIDUMP_STRING in \a file_contents. On
|
||||
//! failure, raises a gtest assertion and returns `nullptr`.
|
||||
//!
|
||||
//! \sa MinidumpStringAtRVAAsString()
|
||||
//! \sa MinidumpUTF8StringAtRVA()
|
||||
const MINIDUMP_STRING* MinidumpStringAtRVA(const std::string& file_contents,
|
||||
RVA rva);
|
||||
|
||||
//! \brief Returns a MinidumpUTF8String located within a minidump file’s
|
||||
//! contents.
|
||||
//!
|
||||
//! If \a rva points outside of the range of \a file_contents, if the string has
|
||||
//! an incorrect length or is not `NUL`-terminated, or if any of the string data
|
||||
//! would lie outside of the range of \a file_contents, this function will fail.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset within the minidump file of the desired
|
||||
//! MinidumpUTF8String.
|
||||
//!
|
||||
//! \return On success, a pointer to the MinidumpUTF8String in \a file_contents.
|
||||
//! On failure, raises a gtest assertion and returns `nullptr`.
|
||||
//!
|
||||
//! \sa MinidumpUTF8StringAtRVAAsString()
|
||||
//! \sa MinidumpStringAtRVA()
|
||||
const MinidumpUTF8String* MinidumpUTF8StringAtRVA(
|
||||
const std::string& file_contents,
|
||||
RVA rva);
|
||||
|
||||
//! \brief Returns the contents of a MINIDUMP_STRING as a `string16`.
|
||||
//!
|
||||
//! This function uses MinidumpStringAtRVA() to obtain a MINIDUMP_STRING, and
|
||||
//! returns the string data as a `string16`.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset within the minidump file of the desired
|
||||
//! MINIDUMP_STRING.
|
||||
//!
|
||||
//! \return On success, the string read from \a file_writer at offset \a rva. On
|
||||
//! failure, returns an empty string, with a nonfatal assertion logged to
|
||||
//! gtest.
|
||||
std::string MinidumpUTF8StringAtRVA(const StringFileWriter& file_writer,
|
||||
RVA rva);
|
||||
//! failure, raises a gtest assertion and returns an empty string.
|
||||
//!
|
||||
//! \sa MinidumpUTF8StringAtRVAAsString()
|
||||
string16 MinidumpStringAtRVAAsString(const std::string& file_contents, RVA rva);
|
||||
|
||||
//! \brief Returns the contents of a MinidumpUTF8String as a `std::string`.
|
||||
//!
|
||||
//! This function uses MinidumpUTF16StringAtRVA() to obtain a
|
||||
//! MinidumpUTF16String, and returns the string data as a `std::string`.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset within the minidump file of the desired
|
||||
//! MinidumpUTF8String.
|
||||
//!
|
||||
//! \return On success, the string read from \a file_writer at offset \a rva. On
|
||||
//! failure, raises a gtest assertion and returns an empty string.
|
||||
//!
|
||||
//! \sa MinidumpStringAtRVAAsString()
|
||||
std::string MinidumpUTF8StringAtRVAAsString(const std::string& file_contents,
|
||||
RVA rva);
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// 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 "minidump/test/minidump_writable_test_util.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
const void* MinidumpWritableAtRVAInternal(const std::string& file_contents,
|
||||
RVA rva) {
|
||||
if (rva >= file_contents.size()) {
|
||||
EXPECT_LT(rva, file_contents.size());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &file_contents[rva];
|
||||
}
|
||||
|
||||
const void* MinidumpWritableAtLocationDescriptorInternal(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location,
|
||||
size_t expected_minimum_size) {
|
||||
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);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RVA end = location.Rva + location.DataSize;
|
||||
if (end > file_contents.size()) {
|
||||
EXPECT_LE(end, file_contents.size());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const void* rv = MinidumpWritableAtRVAInternal(file_contents, location.Rva);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
|
@ -0,0 +1,108 @@
|
|||
// 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_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_
|
||||
#define CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_
|
||||
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
//! \brief Returns an untyped minidump object located within a minidump file’s
|
||||
//! contents, where the offset of the object is known.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset within the minidump file of the desired object.
|
||||
//!
|
||||
//! \return If \a rva is within the range of \a file_contents, returns a pointer
|
||||
//! into \a file_contents at offset \a rva. Otherwise, raises a gtest
|
||||
//! assertion failure and returns `nullptr`.
|
||||
//!
|
||||
//! Do not call this function. Use the typed version, MinidumpWritableAtRVA<>(),
|
||||
//! or another type-specific function.
|
||||
//!
|
||||
//! \sa MinidumpWritableAtLocationDescriptorInternal()
|
||||
const void* MinidumpWritableAtRVAInternal(const std::string& file_contents,
|
||||
RVA rva);
|
||||
|
||||
//! \brief Returns an untyped minidump object located within a minidump file’s
|
||||
//! contents, where the offset and size of the object are known.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] location A MINIDUMP_LOCATION_DESCRIPTOR giving the offset within
|
||||
//! the minidump file of the desired object, as well as its size.
|
||||
//! \param[in] expected_minimum_size The minimum size allowable for the object.
|
||||
//!
|
||||
//! \return If the size of \a location is at least as big as \a
|
||||
//! expected_minimum_size, and if \a location is within the range of \a
|
||||
//! file_contents, returns a pointer into \a file_contents at offset \a rva.
|
||||
//! Otherwise, raises a gtest assertion failure and returns `nullptr`.
|
||||
//!
|
||||
//! Do not call this function. Use the typed version,
|
||||
//! MinidumpWritableAtLocationDescriptor<>(), or another type-specific function.
|
||||
//!
|
||||
//! \sa MinidumpWritableAtRVAInternal()
|
||||
const void* MinidumpWritableAtLocationDescriptorInternal(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location,
|
||||
size_t expected_minimum_size);
|
||||
|
||||
//! \brief Returns a typed minidump object located within a minidump file’s
|
||||
//! contents, where the offset of the object is known.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] rva The offset within the minidump file of the desired object.
|
||||
//!
|
||||
//! \return If \a rva is within the range of \a file_contents, returns a pointer
|
||||
//! into \a file_contents at offset \a rva. Otherwise, raises a gtest
|
||||
//! assertion failure and returns `nullptr`.
|
||||
//!
|
||||
//! \sa MinidumpWritableAtLocationDescriptor<>()
|
||||
template <typename T>
|
||||
const T* MinidumpWritableAtRVA(const std::string& file_contents, RVA rva) {
|
||||
return reinterpret_cast<const T*>(
|
||||
MinidumpWritableAtRVAInternal(file_contents, rva));
|
||||
}
|
||||
|
||||
//! \brief Returns a typed minidump object located within a minidump file’s
|
||||
//! contents, where the offset and size of the object are known.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] location A MINIDUMP_LOCATION_DESCRIPTOR giving the offset within
|
||||
//! the minidump file of the desired object, as well as its size.
|
||||
//!
|
||||
//! \return If the size of \a location is at least as big as the size of the
|
||||
//! requested object, and if \a location is within the range of \a
|
||||
//! file_contents, returns a pointer into \a file_contents at offset \a rva.
|
||||
//! Otherwise, raises a gtest assertion failure and returns `nullptr`.
|
||||
//!
|
||||
//! \sa MinidumpWritableAtRVA()
|
||||
template <typename T>
|
||||
const T* MinidumpWritableAtLocationDescriptor(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
||||
return reinterpret_cast<const T*>(
|
||||
MinidumpWritableAtLocationDescriptorInternal(
|
||||
file_contents, location, sizeof(T)));
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_
|
Загрузка…
Ссылка в новой задаче