// 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 <stddef.h>

#include <string>

#include "base/strings/string16.h"
#include "gtest/gtest.h"
#include "util/file/file_writer.h"
#include "util/misc/implicit_cast.h"

namespace crashpad {
namespace test {

namespace {

//! \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.
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];
}

}  // namespace

const void* MinidumpWritableAtLocationDescriptorInternal(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location,
    size_t expected_size,
    bool allow_oversized_data) {
  if (location.DataSize == 0) {
    EXPECT_EQ(location.Rva, 0u);
    return nullptr;
  }

  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(location.DataSize, expected_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;
}

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(misc->DataType,
              implicit_cast<uint32_t>(IMAGE_DEBUG_MISC_EXENAME));
    return nullptr;
  }

  if (misc->Length != location.DataSize) {
    EXPECT_EQ(misc->Length, location.DataSize);
    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(misc->Data[string_length], '\0');
      return nullptr;
    }
  } else if (misc->Unicode == 1) {
    if (misc->Length % sizeof(base::char16) != 0) {
      EXPECT_EQ(misc->Length % sizeof(base::char16), 0u);
      return nullptr;
    }

    size_t string_length = (misc->Length - offsetof(IMAGE_DEBUG_MISC, Data)) /
                               sizeof(base::char16) -
                           1;
    const base::char16* data16 =
        reinterpret_cast<const base::char16*>(misc->Data);
    if (data16[string_length] != '\0') {
      EXPECT_EQ(data16[string_length], '\0');
      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(header->Signature, implicit_cast<uint32_t>(MINIDUMP_SIGNATURE));
    return nullptr;
  }
  if (header->Version != MINIDUMP_VERSION) {
    EXPECT_EQ(header->Version, implicit_cast<uint32_t>(MINIDUMP_VERSION));
    return nullptr;
  }

  return header;
}

namespace {

struct MinidumpMemoryListTraits {
  using ListType = MINIDUMP_MEMORY_LIST;
  enum : size_t { kElementSize = sizeof(MINIDUMP_MEMORY_DESCRIPTOR) };
  static size_t ElementCount(const ListType* list) {
    return list->NumberOfMemoryRanges;
  }
};

struct MinidumpModuleListTraits {
  using ListType = MINIDUMP_MODULE_LIST;
  enum : size_t { kElementSize = sizeof(MINIDUMP_MODULE) };
  static size_t ElementCount(const ListType* list) {
    return list->NumberOfModules;
  }
};

struct MinidumpUnloadedModuleListTraits {
  using ListType = MINIDUMP_UNLOADED_MODULE_LIST;
  enum : size_t { kElementSize = sizeof(MINIDUMP_UNLOADED_MODULE) };
  static size_t ElementCount(const ListType* list) {
    return list->NumberOfEntries;
  }
};

struct MinidumpThreadListTraits {
  using ListType = MINIDUMP_THREAD_LIST;
  enum : size_t { kElementSize = sizeof(MINIDUMP_THREAD) };
  static size_t ElementCount(const ListType* list) {
    return list->NumberOfThreads;
  }
};

struct MinidumpHandleDataStreamTraits {
  using ListType = MINIDUMP_HANDLE_DATA_STREAM;
  enum : size_t { kElementSize = sizeof(MINIDUMP_HANDLE_DESCRIPTOR) };
  static size_t ElementCount(const ListType* list) {
    return static_cast<size_t>(list->NumberOfDescriptors);
  }
};

struct MinidumpMemoryInfoListTraits {
  using ListType = MINIDUMP_MEMORY_INFO_LIST;
  enum : size_t { kElementSize = sizeof(MINIDUMP_MEMORY_INFO) };
  static size_t ElementCount(const ListType* list) {
    return static_cast<size_t>(list->NumberOfEntries);
  }
};

struct MinidumpModuleCrashpadInfoListTraits {
  using ListType = MinidumpModuleCrashpadInfoList;
  enum : size_t { kElementSize = sizeof(MinidumpModuleCrashpadInfoLink) };
  static size_t ElementCount(const ListType* list) { return list->count; }
};

struct MinidumpSimpleStringDictionaryListTraits {
  using ListType = MinidumpSimpleStringDictionary;
  enum : size_t { kElementSize = sizeof(MinidumpSimpleStringDictionaryEntry) };
  static size_t ElementCount(const ListType* list) { return list->count; }
};

struct MinidumpAnnotationListObjectsTraits {
  using ListType = MinidumpAnnotationList;
  enum : size_t { kElementSize = sizeof(MinidumpAnnotation) };
  static size_t ElementCount(const ListType* list) { return list->count; }
};

template <typename T>
const typename T::ListType* MinidumpListAtLocationDescriptor(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  const typename T::ListType* list =
      TMinidumpWritableAtLocationDescriptor<typename T::ListType>(file_contents,
                                                                  location);
  if (!list) {
    return nullptr;
  }

  size_t expected_size =
      sizeof(typename T::ListType) + T::ElementCount(list) * T::kElementSize;
  if (location.DataSize != expected_size) {
    EXPECT_EQ(location.DataSize, expected_size);
    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_UNLOADED_MODULE_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_UNLOADED_MODULE_LIST>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpListAtLocationDescriptor<MinidumpUnloadedModuleListTraits>(
      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 MINIDUMP_HANDLE_DATA_STREAM*
MinidumpWritableAtLocationDescriptor<MINIDUMP_HANDLE_DATA_STREAM>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpListAtLocationDescriptor<MinidumpHandleDataStreamTraits>(
      file_contents, location);
}

template <>
const MINIDUMP_MEMORY_INFO_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_INFO_LIST>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpListAtLocationDescriptor<MinidumpMemoryInfoListTraits>(
      file_contents, location);
}

template <>
const MinidumpModuleCrashpadInfoList*
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfoList>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpListAtLocationDescriptor<MinidumpModuleCrashpadInfoListTraits>(
      file_contents, location);
}

template <>
const MinidumpSimpleStringDictionary*
MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpListAtLocationDescriptor<
      MinidumpSimpleStringDictionaryListTraits>(file_contents, location);
}

template <>
const MinidumpAnnotationList*
MinidumpWritableAtLocationDescriptor<MinidumpAnnotationList>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpListAtLocationDescriptor<MinidumpAnnotationListObjectsTraits>(
      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(cv_pdb->signature, T::kSignature);
    return nullptr;
  }

  size_t string_length = location.DataSize - offsetof(T, pdb_name) - 1;
  if (cv_pdb->pdb_name[string_length] != '\0') {
    EXPECT_EQ(cv_pdb->pdb_name[string_length], '\0');
    return nullptr;
  }

  return cv_pdb;
}

}  // namespace

template <>
const CodeViewRecordPDB20*
MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB20>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpCVPDBAtLocationDescriptor<CodeViewRecordPDB20>(file_contents,
                                                                location);
}

template <>
const CodeViewRecordPDB70*
MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB70>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  return MinidumpCVPDBAtLocationDescriptor<CodeViewRecordPDB70>(file_contents,
                                                                location);
}

template <>
const CodeViewRecordBuildID*
MinidumpWritableAtLocationDescriptor<CodeViewRecordBuildID>(
    const std::string& file_contents,
    const MINIDUMP_LOCATION_DESCRIPTOR& location) {
  const CodeViewRecordBuildID* cv =
      reinterpret_cast<const CodeViewRecordBuildID*>(
          MinidumpWritableAtLocationDescriptorInternal(
              file_contents,
              location,
              offsetof(CodeViewRecordBuildID, build_id),
              true));

  if (!cv) {
    return nullptr;
  }

  if (cv->signature != CodeViewRecordBuildID::kSignature) {
    return nullptr;
  }

  return cv;
}

TestUInt32MinidumpWritable::TestUInt32MinidumpWritable(uint32_t value)
    : MinidumpWritable(), value_(value) {}

TestUInt32MinidumpWritable::~TestUInt32MinidumpWritable() {}

size_t TestUInt32MinidumpWritable::SizeOfObject() {
  return sizeof(value_);
}

bool TestUInt32MinidumpWritable::WriteObject(FileWriterInterface* file_writer) {
  return file_writer->Write(&value_, sizeof(value_));
}

}  // namespace test
}  // namespace crashpad
