// 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/minidump_module_writer.h"

#include <stddef.h>
#include <string.h>

#include <utility>

#include "base/cxx17_backports.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#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 "minidump/test/minidump_writable_test_util.h"
#include "snapshot/test/test_module_snapshot.h"
#include "test/gtest_death.h"
#include "util/file/string_file.h"
#include "util/misc/implicit_cast.h"
#include "util/misc/uuid.h"

namespace crashpad {
namespace test {
namespace {

void GetModuleListStream(const std::string& file_contents,
                         const MINIDUMP_MODULE_LIST** module_list) {
  constexpr size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
  constexpr size_t kModuleListStreamOffset =
      kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
  constexpr size_t kModulesOffset =
      kModuleListStreamOffset + sizeof(MINIDUMP_MODULE_LIST);

  ASSERT_GE(file_contents.size(), kModulesOffset);

  const MINIDUMP_DIRECTORY* directory;
  const MINIDUMP_HEADER* header =
      MinidumpHeaderAtStart(file_contents, &directory);
  ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
  ASSERT_TRUE(directory);

  ASSERT_EQ(directory[0].StreamType, kMinidumpStreamTypeModuleList);
  EXPECT_EQ(directory[0].Location.Rva, kModuleListStreamOffset);

  *module_list = MinidumpWritableAtLocationDescriptor<MINIDUMP_MODULE_LIST>(
      file_contents, directory[0].Location);
  ASSERT_TRUE(module_list);
}

TEST(MinidumpModuleWriter, EmptyModuleList) {
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_EQ(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MODULE_LIST));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  EXPECT_EQ(module_list->NumberOfModules, 0u);
}

// If |expected_pdb_name| is not nullptr, |codeview_record| is used to locate a
// CodeView record in |file_contents|, and its fields are compared against the
// |expected_pdb_*| values. If |expected_pdb_uuid| is supplied, the CodeView
// record must be a PDB 7.0 link, otherwise, it must be a PDB 2.0 link. If
// |expected_pdb_name| is nullptr, |codeview_record| must not point to anything.
void ExpectCodeViewRecord(const MINIDUMP_LOCATION_DESCRIPTOR* codeview_record,
                          const std::string& file_contents,
                          const char* expected_pdb_name,
                          const UUID* expected_pdb_uuid,
                          time_t expected_pdb_timestamp,
                          uint32_t expected_pdb_age) {
  if (expected_pdb_name) {
    EXPECT_NE(codeview_record->Rva, 0u);

    std::string observed_pdb_name;
    if (expected_pdb_uuid) {
      // The CodeView record should be a PDB 7.0 link.
      const CodeViewRecordPDB70* codeview_pdb70_record =
          MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB70>(
              file_contents, *codeview_record);
      ASSERT_TRUE(codeview_pdb70_record);
      EXPECT_EQ(memcmp(expected_pdb_uuid,
                       &codeview_pdb70_record->uuid,
                       sizeof(codeview_pdb70_record->uuid)),
                0);
      EXPECT_EQ(codeview_pdb70_record->age, expected_pdb_age);

      observed_pdb_name.assign(
          reinterpret_cast<const char*>(&codeview_pdb70_record->pdb_name[0]),
          codeview_record->DataSize - offsetof(CodeViewRecordPDB70, pdb_name));
    } else {
      // The CodeView record should be a PDB 2.0 link.
      const CodeViewRecordPDB20* codeview_pdb20_record =
          MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB20>(
              file_contents, *codeview_record);
      ASSERT_TRUE(codeview_pdb20_record);
      EXPECT_EQ(codeview_pdb20_record->timestamp,
                static_cast<uint32_t>(expected_pdb_timestamp));
      EXPECT_EQ(codeview_pdb20_record->age, expected_pdb_age);

      observed_pdb_name.assign(
          reinterpret_cast<const char*>(&codeview_pdb20_record->pdb_name[0]),
          codeview_record->DataSize - offsetof(CodeViewRecordPDB20, pdb_name));
    }

    // Check for, and then remove, the NUL terminator.
    EXPECT_EQ(observed_pdb_name[observed_pdb_name.size() - 1], '\0');
    observed_pdb_name.resize(observed_pdb_name.size() - 1);

    EXPECT_EQ(observed_pdb_name, expected_pdb_name);
  } else {
    // There should be no CodeView record.
    EXPECT_EQ(codeview_record->DataSize, 0u);
    EXPECT_EQ(codeview_record->Rva, 0u);
  }
}

// If |expected_debug_name| is not nullptr, |misc_record| is used to locate a
// miscellanous debugging record in |file_contents|, and its fields are compared
// against the the |expected_debug_*| values. If |expected_debug_name| is
// nullptr, |misc_record| must not point to anything.
void ExpectMiscellaneousDebugRecord(
    const MINIDUMP_LOCATION_DESCRIPTOR* misc_record,
    const std::string& file_contents,
    const char* expected_debug_name,
    uint32_t expected_debug_type,
    bool expected_debug_utf16) {
  if (expected_debug_name) {
    EXPECT_NE(misc_record->Rva, 0u);
    const IMAGE_DEBUG_MISC* misc_debug_record =
        MinidumpWritableAtLocationDescriptor<IMAGE_DEBUG_MISC>(file_contents,
                                                               *misc_record);
    ASSERT_TRUE(misc_debug_record);
    EXPECT_EQ(misc_debug_record->DataType, expected_debug_type);
    EXPECT_EQ(misc_debug_record->Unicode != 0, expected_debug_utf16);
    EXPECT_EQ(misc_debug_record->Reserved[0], 0u);
    EXPECT_EQ(misc_debug_record->Reserved[1], 0u);
    EXPECT_EQ(misc_debug_record->Reserved[2], 0u);

    // Check for the NUL terminator.
    size_t bytes_available =
        misc_debug_record->Length - offsetof(IMAGE_DEBUG_MISC, Data);
    EXPECT_EQ(misc_debug_record->Data[bytes_available - 1], '\0');
    std::string observed_data(
        reinterpret_cast<const char*>(misc_debug_record->Data));

    size_t bytes_used;
    if (misc_debug_record->Unicode) {
      std::u16string observed_data_utf16(
          reinterpret_cast<const char16_t*>(misc_debug_record->Data));
      bytes_used = (observed_data_utf16.size() + 1) * sizeof(char16_t);
      observed_data = base::UTF16ToUTF8(observed_data_utf16);
    } else {
      observed_data = reinterpret_cast<const char*>(misc_debug_record->Data);
      bytes_used = (observed_data.size() + 1) * sizeof(char);
    }
    EXPECT_LE(bytes_used, bytes_available);

    // Make sure that any padding bytes after the first NUL are also NUL.
    for (size_t index = bytes_used; index < bytes_available; ++index) {
      EXPECT_EQ(misc_debug_record->Data[index], '\0');
    }

    EXPECT_EQ(observed_data, expected_debug_name);
  } else {
    // There should be no miscellaneous debugging record.
    EXPECT_EQ(misc_record->DataSize, 0u);
    EXPECT_EQ(misc_record->Rva, 0u);
  }
}

// ExpectModule() verifies that |expected| matches |observed|. Fields that are
// supposed to contain constant magic numbers are verified against the expected
// constants instead of |expected|. Reserved fields are verified to be 0. RVA
// and MINIDUMP_LOCATION_DESCRIPTOR fields are not verified against |expected|.
// Instead, |ModuleNameRva| is used to locate the module name, which is compared
// against |expected_module_name|. ExpectCodeViewRecord() and
// ExpectMiscellaneousDebugRecord() are used to verify the |CvRecord| and
// |MiscRecord| fields against |expected_pdb_*| and |expected_debug_*|
// parameters, respectively.
void ExpectModule(const MINIDUMP_MODULE* expected,
                  const MINIDUMP_MODULE* observed,
                  const std::string& file_contents,
                  const std::string& expected_module_name,
                  const char* expected_pdb_name,
                  const UUID* expected_pdb_uuid,
                  time_t expected_pdb_timestamp,
                  uint32_t expected_pdb_age,
                  const char* expected_debug_name,
                  uint32_t expected_debug_type,
                  bool expected_debug_utf16) {
  MINIDUMP_MODULE expected_module, observed_module;
  memcpy(&expected_module, expected, sizeof(expected_module));
  memcpy(&observed_module, observed, sizeof(observed_module));

  EXPECT_EQ(observed_module.BaseOfImage, expected_module.BaseOfImage);
  EXPECT_EQ(observed_module.SizeOfImage, expected_module.SizeOfImage);
  EXPECT_EQ(observed_module.CheckSum, expected_module.CheckSum);
  EXPECT_EQ(observed_module.TimeDateStamp, expected_module.TimeDateStamp);
  EXPECT_EQ(observed_module.VersionInfo.dwSignature,
            implicit_cast<uint32_t>(VS_FFI_SIGNATURE));
  EXPECT_EQ(observed_module.VersionInfo.dwStrucVersion,
            implicit_cast<uint32_t>(VS_FFI_STRUCVERSION));
  EXPECT_EQ(observed_module.VersionInfo.dwFileVersionMS,
            expected_module.VersionInfo.dwFileVersionMS);
  EXPECT_EQ(observed_module.VersionInfo.dwFileVersionLS,
            expected_module.VersionInfo.dwFileVersionLS);
  EXPECT_EQ(observed_module.VersionInfo.dwProductVersionMS,
            expected_module.VersionInfo.dwProductVersionMS);
  EXPECT_EQ(observed_module.VersionInfo.dwProductVersionLS,
            expected_module.VersionInfo.dwProductVersionLS);
  EXPECT_EQ(observed_module.VersionInfo.dwFileFlagsMask,
            expected_module.VersionInfo.dwFileFlagsMask);
  EXPECT_EQ(observed_module.VersionInfo.dwFileFlags,
            expected_module.VersionInfo.dwFileFlags);
  EXPECT_EQ(observed_module.VersionInfo.dwFileOS,
            expected_module.VersionInfo.dwFileOS);
  EXPECT_EQ(observed_module.VersionInfo.dwFileType,
            expected_module.VersionInfo.dwFileType);
  EXPECT_EQ(observed_module.VersionInfo.dwFileSubtype,
            expected_module.VersionInfo.dwFileSubtype);
  EXPECT_EQ(observed_module.VersionInfo.dwFileDateMS,
            expected_module.VersionInfo.dwFileDateMS);
  EXPECT_EQ(observed_module.VersionInfo.dwFileDateLS,
            expected_module.VersionInfo.dwFileDateLS);

  uint64_t reserved0, reserved1;
  memcpy(&reserved0, &observed_module.Reserved0, sizeof(reserved0));
  memcpy(&reserved1, &observed_module.Reserved1, sizeof(reserved1));

  EXPECT_EQ(reserved0, 0u);
  EXPECT_EQ(reserved1, 0u);

  EXPECT_NE(observed_module.ModuleNameRva, 0u);
  std::u16string observed_module_name_utf16 =
      MinidumpStringAtRVAAsString(file_contents, observed_module.ModuleNameRva);
  std::u16string expected_module_name_utf16 =
      base::UTF8ToUTF16(expected_module_name);
  EXPECT_EQ(observed_module_name_utf16, expected_module_name_utf16);

  ASSERT_NO_FATAL_FAILURE(ExpectCodeViewRecord(&observed_module.CvRecord,
                                               file_contents,
                                               expected_pdb_name,
                                               expected_pdb_uuid,
                                               expected_pdb_timestamp,
                                               expected_pdb_age));

  ASSERT_NO_FATAL_FAILURE(
      ExpectMiscellaneousDebugRecord(&observed_module.MiscRecord,
                                     file_contents,
                                     expected_debug_name,
                                     expected_debug_type,
                                     expected_debug_utf16));
}

// ExpectModuleWithBuildIDCv() is like ExpectModule( but expects the module to
// have a BuildID CodeView Record.
void ExpectModuleWithBuildIDCv(const MINIDUMP_MODULE* expected,
                               const MINIDUMP_MODULE* observed,
                               const std::string& file_contents,
                               const std::string& expected_module_name,
                               const std::vector<uint8_t>& expected_build_id) {
  EXPECT_EQ(observed->BaseOfImage, expected->BaseOfImage);
  EXPECT_EQ(observed->SizeOfImage, expected->SizeOfImage);
  EXPECT_EQ(observed->CheckSum, expected->CheckSum);
  EXPECT_EQ(observed->TimeDateStamp, expected->TimeDateStamp);
  EXPECT_EQ(observed->VersionInfo.dwSignature,
            implicit_cast<uint32_t>(VS_FFI_SIGNATURE));
  EXPECT_EQ(observed->VersionInfo.dwStrucVersion,
            implicit_cast<uint32_t>(VS_FFI_STRUCVERSION));
  EXPECT_EQ(observed->VersionInfo.dwFileVersionMS,
            expected->VersionInfo.dwFileVersionMS);
  EXPECT_EQ(observed->VersionInfo.dwFileVersionLS,
            expected->VersionInfo.dwFileVersionLS);
  EXPECT_EQ(observed->VersionInfo.dwProductVersionMS,
            expected->VersionInfo.dwProductVersionMS);
  EXPECT_EQ(observed->VersionInfo.dwProductVersionLS,
            expected->VersionInfo.dwProductVersionLS);
  EXPECT_EQ(observed->VersionInfo.dwFileFlagsMask,
            expected->VersionInfo.dwFileFlagsMask);
  EXPECT_EQ(observed->VersionInfo.dwFileFlags,
            expected->VersionInfo.dwFileFlags);
  EXPECT_EQ(observed->VersionInfo.dwFileOS, expected->VersionInfo.dwFileOS);
  EXPECT_EQ(observed->VersionInfo.dwFileType, expected->VersionInfo.dwFileType);
  EXPECT_EQ(observed->VersionInfo.dwFileSubtype,
            expected->VersionInfo.dwFileSubtype);
  EXPECT_EQ(observed->VersionInfo.dwFileDateMS,
            expected->VersionInfo.dwFileDateMS);
  EXPECT_EQ(observed->VersionInfo.dwFileDateLS,
            expected->VersionInfo.dwFileDateLS);

  uint64_t reserved0, reserved1;
  memcpy(&reserved0, &observed->Reserved0, sizeof(reserved0));
  memcpy(&reserved1, &observed->Reserved1, sizeof(reserved1));

  EXPECT_EQ(reserved0, 0u);
  EXPECT_EQ(reserved1, 0u);

  EXPECT_NE(observed->ModuleNameRva, 0u);
  std::u16string observed_module_name_utf16 =
      MinidumpStringAtRVAAsString(file_contents, observed->ModuleNameRva);
  std::u16string expected_module_name_utf16 =
      base::UTF8ToUTF16(expected_module_name);
  EXPECT_EQ(observed_module_name_utf16, expected_module_name_utf16);

  const CodeViewRecordBuildID* codeview_build_id_record =
      MinidumpWritableAtLocationDescriptor<CodeViewRecordBuildID>(
          file_contents, observed->CvRecord);
  ASSERT_TRUE(codeview_build_id_record);
  EXPECT_EQ(memcmp(expected_build_id.data(),
                   &codeview_build_id_record->build_id,
                   expected_build_id.size()),
            0);
}

TEST(MinidumpModuleWriter, EmptyModule) {
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();

  static constexpr char kModuleName[] = "test_executable";

  auto module_writer = std::make_unique<MinidumpModuleWriter>();
  module_writer->SetName(kModuleName);

  module_list_writer->AddModule(std::move(module_writer));
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  EXPECT_EQ(module_list->NumberOfModules, 1u);

  MINIDUMP_MODULE expected = {};
  ASSERT_NO_FATAL_FAILURE(ExpectModule(&expected,
                                       &module_list->Modules[0],
                                       string_file.string(),
                                       kModuleName,
                                       nullptr,
                                       nullptr,
                                       0,
                                       0,
                                       nullptr,
                                       0,
                                       false));
}

TEST(MinidumpModuleWriter, OneModule) {
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();

  static constexpr char kModuleName[] = "statically_linked";
  constexpr uint64_t kModuleBase = 0x10da69000;
  constexpr uint32_t kModuleSize = 0x1000;
  constexpr uint32_t kChecksum = 0x76543210;
  constexpr time_t kTimestamp = 0x386d4380;
  constexpr uint32_t kFileVersionMS = 0x00010002;
  constexpr uint32_t kFileVersionLS = 0x00030004;
  constexpr uint32_t kProductVersionMS = 0x00050006;
  constexpr uint32_t kProductVersionLS = 0x00070008;
  constexpr uint32_t kFileFlagsMask = VS_FF_DEBUG | VS_FF_PRERELEASE |
                                      VS_FF_PATCHED | VS_FF_PRIVATEBUILD |
                                      VS_FF_INFOINFERRED | VS_FF_SPECIALBUILD;
  constexpr uint32_t kFileFlags = VS_FF_PRIVATEBUILD | VS_FF_SPECIALBUILD;
  constexpr uint32_t kFileOS = VOS_DOS;
  constexpr uint32_t kFileType = VFT_DRV;
  constexpr uint32_t kFileSubtype = VFT2_DRV_KEYBOARD;
  static constexpr char kPDBName[] = "statical.pdb";
  static constexpr uint8_t kPDBUUIDBytes[16] = {0xfe,
                                                0xdc,
                                                0xba,
                                                0x98,
                                                0x76,
                                                0x54,
                                                0x32,
                                                0x10,
                                                0x08,
                                                0x19,
                                                0x2a,
                                                0x3b,
                                                0x4c,
                                                0x5d,
                                                0x6e,
                                                0x7f};
  UUID pdb_uuid;
  pdb_uuid.InitializeFromBytes(kPDBUUIDBytes);
  constexpr uint32_t kPDBAge = 1;
  constexpr uint32_t kDebugType = IMAGE_DEBUG_MISC_EXENAME;
  static constexpr char kDebugName[] = "statical.dbg";
  constexpr bool kDebugUTF16 = false;

  auto module_writer = std::make_unique<MinidumpModuleWriter>();
  module_writer->SetName(kModuleName);
  module_writer->SetImageBaseAddress(kModuleBase);
  module_writer->SetImageSize(kModuleSize);
  module_writer->SetChecksum(kChecksum);
  module_writer->SetTimestamp(kTimestamp);
  module_writer->SetFileVersion(kFileVersionMS >> 16,
                                kFileVersionMS & 0xffff,
                                kFileVersionLS >> 16,
                                kFileVersionLS & 0xffff);
  module_writer->SetProductVersion(kProductVersionMS >> 16,
                                   kProductVersionMS & 0xffff,
                                   kProductVersionLS >> 16,
                                   kProductVersionLS & 0xffff);
  module_writer->SetFileFlagsAndMask(kFileFlags, kFileFlagsMask);
  module_writer->SetFileOS(kFileOS);
  module_writer->SetFileTypeAndSubtype(kFileType, kFileSubtype);

  auto codeview_pdb70_writer =
      std::make_unique<MinidumpModuleCodeViewRecordPDB70Writer>();
  codeview_pdb70_writer->SetPDBName(kPDBName);
  codeview_pdb70_writer->SetUUIDAndAge(pdb_uuid, kPDBAge);
  module_writer->SetCodeViewRecord(std::move(codeview_pdb70_writer));

  auto misc_debug_writer =
      std::make_unique<MinidumpModuleMiscDebugRecordWriter>();
  misc_debug_writer->SetDataType(kDebugType);
  misc_debug_writer->SetData(kDebugName, kDebugUTF16);
  module_writer->SetMiscDebugRecord(std::move(misc_debug_writer));

  module_list_writer->AddModule(std::move(module_writer));
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  EXPECT_EQ(module_list->NumberOfModules, 1u);

  MINIDUMP_MODULE expected = {};
  expected.BaseOfImage = kModuleBase;
  expected.SizeOfImage = kModuleSize;
  expected.CheckSum = kChecksum;
  expected.TimeDateStamp = kTimestamp;
  expected.VersionInfo.dwFileVersionMS = kFileVersionMS;
  expected.VersionInfo.dwFileVersionLS = kFileVersionLS;
  expected.VersionInfo.dwProductVersionMS = kProductVersionMS;
  expected.VersionInfo.dwProductVersionLS = kProductVersionLS;
  expected.VersionInfo.dwFileFlagsMask = kFileFlagsMask;
  expected.VersionInfo.dwFileFlags = kFileFlags;
  expected.VersionInfo.dwFileOS = kFileOS;
  expected.VersionInfo.dwFileType = kFileType;
  expected.VersionInfo.dwFileSubtype = kFileSubtype;

  ASSERT_NO_FATAL_FAILURE(ExpectModule(&expected,
                                       &module_list->Modules[0],
                                       string_file.string(),
                                       kModuleName,
                                       kPDBName,
                                       &pdb_uuid,
                                       0,
                                       kPDBAge,
                                       kDebugName,
                                       kDebugType,
                                       kDebugUTF16));
}

TEST(MinidumpModuleWriter, OneModule_CodeViewUsesPDB20_MiscUsesUTF16) {
  // MinidumpModuleWriter.OneModule tested with a PDB 7.0 link as the CodeView
  // record and an IMAGE_DEBUG_MISC record in UTF-8. This test exercises the
  // alternatives, a PDB 2.0 link as the CodeView record and an IMAGE_DEBUG_MISC
  // record with UTF-16 data.
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();

  static constexpr char kModuleName[] = "dinosaur";
  static constexpr char kPDBName[] = "d1n05.pdb";
  constexpr time_t kPDBTimestamp = 0x386d4380;
  constexpr uint32_t kPDBAge = 1;
  constexpr uint32_t kDebugType = IMAGE_DEBUG_MISC_EXENAME;
  static constexpr char kDebugName[] = "d1n05.dbg";
  constexpr bool kDebugUTF16 = true;

  auto module_writer = std::make_unique<MinidumpModuleWriter>();
  module_writer->SetName(kModuleName);

  auto codeview_pdb20_writer =
      std::make_unique<MinidumpModuleCodeViewRecordPDB20Writer>();
  codeview_pdb20_writer->SetPDBName(kPDBName);
  codeview_pdb20_writer->SetTimestampAndAge(kPDBTimestamp, kPDBAge);
  module_writer->SetCodeViewRecord(std::move(codeview_pdb20_writer));

  auto misc_debug_writer =
      std::make_unique<MinidumpModuleMiscDebugRecordWriter>();
  misc_debug_writer->SetDataType(kDebugType);
  misc_debug_writer->SetData(kDebugName, kDebugUTF16);
  module_writer->SetMiscDebugRecord(std::move(misc_debug_writer));

  module_list_writer->AddModule(std::move(module_writer));
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  EXPECT_EQ(module_list->NumberOfModules, 1u);

  MINIDUMP_MODULE expected = {};

  ASSERT_NO_FATAL_FAILURE(ExpectModule(&expected,
                                       &module_list->Modules[0],
                                       string_file.string(),
                                       kModuleName,
                                       kPDBName,
                                       nullptr,
                                       kPDBTimestamp,
                                       kPDBAge,
                                       kDebugName,
                                       kDebugType,
                                       kDebugUTF16));
}

TEST(MinidumpModuleWriter, OneModule_CodeViewBuildID) {
  // MinidumpModuleWriter.OneModule tested with a BuildID CodeView
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();

  static constexpr char kModuleName[] = "dinosaur";
  static constexpr char kBuildID[] =
      "averylonghashcodeormaybeitsjustrandomnumbershardtosay";

  std::vector<uint8_t> build_id_data(kBuildID, kBuildID + 53);

  auto module_writer = std::make_unique<MinidumpModuleWriter>();
  module_writer->SetName(kModuleName);

  auto codeview_build_id_writer =
      std::make_unique<MinidumpModuleCodeViewRecordBuildIDWriter>();
  codeview_build_id_writer->SetBuildID(build_id_data);
  module_writer->SetCodeViewRecord(std::move(codeview_build_id_writer));

  module_list_writer->AddModule(std::move(module_writer));
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  EXPECT_EQ(module_list->NumberOfModules, 1u);

  MINIDUMP_MODULE expected = {};

  ASSERT_NO_FATAL_FAILURE(ExpectModuleWithBuildIDCv(&expected,
                                                    &module_list->Modules[0],
                                                    string_file.string(),
                                                    kModuleName,
                                                    build_id_data));
}

TEST(MinidumpModuleWriter, ThreeModules) {
  // As good exercise, this test uses three modules, one with a PDB 7.0 link as
  // its CodeView record, one with no CodeView record, and one with a PDB 2.0
  // link as its CodeView record.
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();

  static constexpr char kModuleName0[] = "main";
  constexpr uint64_t kModuleBase0 = 0x100101000;
  constexpr uint32_t kModuleSize0 = 0xf000;
  static constexpr char kPDBName0[] = "main";
  static constexpr uint8_t kPDBUUIDBytes0[16] = {0xaa,
                                                 0xbb,
                                                 0xcc,
                                                 0xdd,
                                                 0xee,
                                                 0xff,
                                                 0x00,
                                                 0x11,
                                                 0x22,
                                                 0x33,
                                                 0x44,
                                                 0x55,
                                                 0x66,
                                                 0x77,
                                                 0x88,
                                                 0x99};
  UUID pdb_uuid_0;
  pdb_uuid_0.InitializeFromBytes(kPDBUUIDBytes0);
  constexpr uint32_t kPDBAge0 = 0;

  static constexpr char kModuleName1[] = "ld.so";
  constexpr uint64_t kModuleBase1 = 0x200202000;
  constexpr uint32_t kModuleSize1 = 0x1e000;

  static constexpr char kModuleName2[] = "libc.so";
  constexpr uint64_t kModuleBase2 = 0x300303000;
  constexpr uint32_t kModuleSize2 = 0x2d000;
  static constexpr char kPDBName2[] = "libc.so";
  constexpr time_t kPDBTimestamp2 = 0x386d4380;
  constexpr uint32_t kPDBAge2 = 2;

  auto module_writer_0 = std::make_unique<MinidumpModuleWriter>();
  module_writer_0->SetName(kModuleName0);
  module_writer_0->SetImageBaseAddress(kModuleBase0);
  module_writer_0->SetImageSize(kModuleSize0);

  auto codeview_pdb70_writer_0 =
      std::make_unique<MinidumpModuleCodeViewRecordPDB70Writer>();
  codeview_pdb70_writer_0->SetPDBName(kPDBName0);
  codeview_pdb70_writer_0->SetUUIDAndAge(pdb_uuid_0, kPDBAge0);
  module_writer_0->SetCodeViewRecord(std::move(codeview_pdb70_writer_0));

  module_list_writer->AddModule(std::move(module_writer_0));

  auto module_writer_1 = std::make_unique<MinidumpModuleWriter>();
  module_writer_1->SetName(kModuleName1);
  module_writer_1->SetImageBaseAddress(kModuleBase1);
  module_writer_1->SetImageSize(kModuleSize1);

  module_list_writer->AddModule(std::move(module_writer_1));

  auto module_writer_2 = std::make_unique<MinidumpModuleWriter>();
  module_writer_2->SetName(kModuleName2);
  module_writer_2->SetImageBaseAddress(kModuleBase2);
  module_writer_2->SetImageSize(kModuleSize2);

  auto codeview_pdb70_writer_2 =
      std::make_unique<MinidumpModuleCodeViewRecordPDB20Writer>();
  codeview_pdb70_writer_2->SetPDBName(kPDBName2);
  codeview_pdb70_writer_2->SetTimestampAndAge(kPDBTimestamp2, kPDBAge2);
  module_writer_2->SetCodeViewRecord(std::move(codeview_pdb70_writer_2));

  module_list_writer->AddModule(std::move(module_writer_2));

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  EXPECT_EQ(module_list->NumberOfModules, 3u);

  MINIDUMP_MODULE expected = {};

  {
    SCOPED_TRACE("module 0");

    expected.BaseOfImage = kModuleBase0;
    expected.SizeOfImage = kModuleSize0;

    ASSERT_NO_FATAL_FAILURE(ExpectModule(&expected,
                                         &module_list->Modules[0],
                                         string_file.string(),
                                         kModuleName0,
                                         kPDBName0,
                                         &pdb_uuid_0,
                                         0,
                                         kPDBAge0,
                                         nullptr,
                                         0,
                                         false));
  }

  {
    SCOPED_TRACE("module 1");

    expected.BaseOfImage = kModuleBase1;
    expected.SizeOfImage = kModuleSize1;

    ASSERT_NO_FATAL_FAILURE(ExpectModule(&expected,
                                         &module_list->Modules[1],
                                         string_file.string(),
                                         kModuleName1,
                                         nullptr,
                                         nullptr,
                                         0,
                                         0,
                                         nullptr,
                                         0,
                                         false));
  }

  {
    SCOPED_TRACE("module 2");

    expected.BaseOfImage = kModuleBase2;
    expected.SizeOfImage = kModuleSize2;

    ASSERT_NO_FATAL_FAILURE(ExpectModule(&expected,
                                         &module_list->Modules[2],
                                         string_file.string(),
                                         kModuleName2,
                                         kPDBName2,
                                         nullptr,
                                         kPDBTimestamp2,
                                         kPDBAge2,
                                         nullptr,
                                         0,
                                         false));
  }
}

void InitializeTestModuleSnapshotFromMinidumpModule(
    TestModuleSnapshot* module_snapshot,
    const MINIDUMP_MODULE& minidump_module,
    const std::string& name,
    const std::string& pdb_name,
    const crashpad::UUID& uuid,
    uint32_t age) {
  module_snapshot->SetName(name);

  module_snapshot->SetAddressAndSize(minidump_module.BaseOfImage,
                                     minidump_module.SizeOfImage);
  module_snapshot->SetTimestamp(minidump_module.TimeDateStamp);
  module_snapshot->SetFileVersion(
      minidump_module.VersionInfo.dwFileVersionMS >> 16,
      minidump_module.VersionInfo.dwFileVersionMS & 0xffff,
      minidump_module.VersionInfo.dwFileVersionLS >> 16,
      minidump_module.VersionInfo.dwFileVersionLS & 0xffff);
  module_snapshot->SetSourceVersion(
      minidump_module.VersionInfo.dwProductVersionMS >> 16,
      minidump_module.VersionInfo.dwProductVersionMS & 0xffff,
      minidump_module.VersionInfo.dwProductVersionLS >> 16,
      minidump_module.VersionInfo.dwProductVersionLS & 0xffff);

  ModuleSnapshot::ModuleType module_type;
  switch (minidump_module.VersionInfo.dwFileType) {
    case VFT_APP:
      module_type = ModuleSnapshot::kModuleTypeExecutable;
      break;
    case VFT_DLL:
      module_type = ModuleSnapshot::kModuleTypeSharedLibrary;
      break;
    default:
      module_type = ModuleSnapshot::kModuleTypeUnknown;
      break;
  }
  module_snapshot->SetModuleType(module_type);

  module_snapshot->SetUUIDAndAge(uuid, age);
  module_snapshot->SetDebugFileName(pdb_name);
}

TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
  MINIDUMP_MODULE expect_modules[3] = {};
  const char* module_paths[base::size(expect_modules)] = {};
  const char* module_pdbs[base::size(expect_modules)] = {};
  UUID uuids[base::size(expect_modules)] = {};
  uint32_t ages[base::size(expect_modules)] = {};

  expect_modules[0].BaseOfImage = 0x100101000;
  expect_modules[0].SizeOfImage = 0xf000;
  expect_modules[0].TimeDateStamp = 0x01234567;
  expect_modules[0].VersionInfo.dwFileVersionMS = 0x00010002;
  expect_modules[0].VersionInfo.dwFileVersionLS = 0x00030004;
  expect_modules[0].VersionInfo.dwProductVersionMS = 0x00050006;
  expect_modules[0].VersionInfo.dwProductVersionLS = 0x00070008;
  expect_modules[0].VersionInfo.dwFileType = VFT_APP;
  module_paths[0] = "/usr/bin/true";
  module_pdbs[0] = "true";
  static constexpr uint8_t kUUIDBytes0[16] = {0x00,
                                              0x11,
                                              0x22,
                                              0x33,
                                              0x44,
                                              0x55,
                                              0x66,
                                              0x77,
                                              0x88,
                                              0x99,
                                              0xaa,
                                              0xbb,
                                              0xcc,
                                              0xdd,
                                              0xee,
                                              0xff};
  uuids[0].InitializeFromBytes(kUUIDBytes0);
  ages[0] = 10;

  expect_modules[1].BaseOfImage = 0x200202000;
  expect_modules[1].SizeOfImage = 0x1e1000;
  expect_modules[1].TimeDateStamp = 0x89abcdef;
  expect_modules[1].VersionInfo.dwFileVersionMS = 0x0009000a;
  expect_modules[1].VersionInfo.dwFileVersionLS = 0x000b000c;
  expect_modules[1].VersionInfo.dwProductVersionMS = 0x000d000e;
  expect_modules[1].VersionInfo.dwProductVersionLS = 0x000f0000;
  expect_modules[1].VersionInfo.dwFileType = VFT_DLL;
  module_paths[1] = "/usr/lib/libSystem.B.dylib";
  module_pdbs[1] = "libSystem.B.dylib.pdb";
  static constexpr uint8_t kUUIDBytes1[16] = {0x00,
                                              0x01,
                                              0x02,
                                              0x03,
                                              0x04,
                                              0x05,
                                              0x06,
                                              0x07,
                                              0x08,
                                              0x09,
                                              0x0a,
                                              0x0b,
                                              0x0c,
                                              0x0d,
                                              0x0e,
                                              0x0f};
  uuids[1].InitializeFromBytes(kUUIDBytes1);
  ages[1] = 20;

  expect_modules[2].BaseOfImage = 0x300303000;
  expect_modules[2].SizeOfImage = 0x2d000;
  expect_modules[2].TimeDateStamp = 0x76543210;
  expect_modules[2].VersionInfo.dwFileVersionMS = 0x11112222;
  expect_modules[2].VersionInfo.dwFileVersionLS = 0x33334444;
  expect_modules[2].VersionInfo.dwProductVersionMS = 0x9999aaaa;
  expect_modules[2].VersionInfo.dwProductVersionLS = 0xbbbbcccc;
  expect_modules[2].VersionInfo.dwFileType = VFT_UNKNOWN;
  module_paths[2] = "/usr/lib/dyld";
  module_pdbs[2] = "/usr/lib/dyld.pdb";
  static constexpr uint8_t kUUIDBytes2[16] = {0xff,
                                              0xfe,
                                              0xfd,
                                              0xfc,
                                              0xfb,
                                              0xfa,
                                              0xf9,
                                              0xf8,
                                              0xf7,
                                              0xf6,
                                              0xf5,
                                              0xf4,
                                              0xf3,
                                              0xf2,
                                              0xf1,
                                              0xf0};
  uuids[2].InitializeFromBytes(kUUIDBytes2);
  ages[2] = 30;

  std::vector<std::unique_ptr<TestModuleSnapshot>> module_snapshots_owner;
  std::vector<const ModuleSnapshot*> module_snapshots;
  for (size_t index = 0; index < base::size(expect_modules); ++index) {
    module_snapshots_owner.push_back(std::make_unique<TestModuleSnapshot>());
    TestModuleSnapshot* module_snapshot = module_snapshots_owner.back().get();
    InitializeTestModuleSnapshotFromMinidumpModule(module_snapshot,
                                                   expect_modules[index],
                                                   module_paths[index],
                                                   module_pdbs[index],
                                                   uuids[index],
                                                   ages[index]);
    module_snapshots.push_back(module_snapshot);
  }

  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();
  module_list_writer->InitializeFromSnapshot(module_snapshots);

  MinidumpFileWriter minidump_file_writer;
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MODULE_LIST* module_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetModuleListStream(string_file.string(), &module_list));

  ASSERT_EQ(module_list->NumberOfModules, 3u);

  for (size_t index = 0; index < module_list->NumberOfModules; ++index) {
    SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index));
    ASSERT_NO_FATAL_FAILURE(ExpectModule(&expect_modules[index],
                                         &module_list->Modules[index],
                                         string_file.string(),
                                         module_paths[index],
                                         module_pdbs[index],
                                         &uuids[index],
                                         0,
                                         ages[index],
                                         nullptr,
                                         0,
                                         false));
  }
}

TEST(MinidumpModuleWriterDeathTest, NoModuleName) {
  MinidumpFileWriter minidump_file_writer;
  auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();
  auto module_writer = std::make_unique<MinidumpModuleWriter>();
  module_list_writer->AddModule(std::move(module_writer));
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));

  StringFile string_file;
  ASSERT_DEATH_CHECK(minidump_file_writer.WriteEverything(&string_file),
                     "name_");
}

}  // namespace
}  // namespace test
}  // namespace crashpad
