// Copyright (c) 2010, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Unit tests for FileID

#include <elf.h>
#include <stdlib.h>

#include <string>
#include <vector>

#include "common/linux/elf_gnu_compat.h"
#include "common/linux/elfutils.h"
#include "common/linux/file_id.h"
#include "common/linux/safe_readlink.h"
#include "common/linux/synth_elf.h"
#include "common/test_assembler.h"
#include "common/tests/auto_tempdir.h"
#include "common/using_std_string.h"
#include "breakpad_googletest_includes.h"

using namespace google_breakpad;
using google_breakpad::synth_elf::ELF;
using google_breakpad::synth_elf::Notes;
using google_breakpad::test_assembler::kLittleEndian;
using google_breakpad::test_assembler::Section;
using std::vector;
using ::testing::Types;

namespace {

// Simply calling Section::Append(size, byte) produces a uninteresting pattern
// that tends to get hashed to 0000...0000. This populates the section with
// data to produce better hashes.
void PopulateSection(Section* section, int size, int prime_number) {
  for (int i = 0; i < size; i++)
    section->Append(1, (i % prime_number) % 256);
}

typedef wasteful_vector<uint8_t> id_vector;

}  // namespace

#ifndef __ANDROID__
// This test is disabled on Android: It will always fail, since there is no
// 'strip' binary installed on test devices.
TEST(FileIDStripTest, StripSelf) {
  // Calculate the File ID of this binary using
  // FileID::ElfFileIdentifier, then make a copy of this binary,
  // strip it, and ensure that the result is the same.
  char exe_name[PATH_MAX];
  ASSERT_TRUE(SafeReadLink("/proc/self/exe", exe_name));

  // copy our binary to a temp file, and strip it
  AutoTempDir temp_dir;
  string templ = temp_dir.path() + "/file-id-unittest";
  char cmdline[4096];
  sprintf(cmdline, "cp \"%s\" \"%s\"", exe_name, templ.c_str());
  ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
  sprintf(cmdline, "chmod u+w \"%s\"", templ.c_str());
  ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
  sprintf(cmdline, "strip \"%s\"", templ.c_str());
  ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;

  PageAllocator allocator;
  id_vector identifier1(&allocator, kDefaultBuildIdSize);
  id_vector identifier2(&allocator, kDefaultBuildIdSize);

  FileID fileid1(exe_name);
  EXPECT_TRUE(fileid1.ElfFileIdentifier(identifier1));
  FileID fileid2(templ.c_str());
  EXPECT_TRUE(fileid2.ElfFileIdentifier(identifier2));

  string identifier_string1 =
      FileID::ConvertIdentifierToUUIDString(identifier1);
  string identifier_string2 =
      FileID::ConvertIdentifierToUUIDString(identifier2);
  EXPECT_EQ(identifier_string1, identifier_string2);
}
#endif  // !__ANDROID__

template<typename ElfClass>
class FileIDTest : public testing::Test {
public:
  void GetElfContents(ELF& elf) {
    string contents;
    ASSERT_TRUE(elf.GetContents(&contents));
    ASSERT_LT(0U, contents.size());

    elfdata_v.clear();
    elfdata_v.insert(elfdata_v.begin(), contents.begin(), contents.end());
    elfdata = &elfdata_v[0];
  }

  id_vector make_vector() {
    return id_vector(&allocator, kDefaultBuildIdSize);
  }

  template<size_t N>
  string get_file_id(const uint8_t (&data)[N]) {
    id_vector expected_identifier(make_vector());
    expected_identifier.insert(expected_identifier.end(),
                               &data[0],
                               data + N);
    return FileID::ConvertIdentifierToUUIDString(expected_identifier);
  }

  vector<uint8_t> elfdata_v;
  uint8_t* elfdata;
  PageAllocator allocator;
};

typedef Types<ElfClass32, ElfClass64> ElfClasses;

TYPED_TEST_SUITE(FileIDTest, ElfClasses);

TYPED_TEST(FileIDTest, ElfClass) {
  const char expected_identifier_string[] =
      "80808080808000000000008080808080";
  const size_t kTextSectionSize = 128;

  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
  Section text(kLittleEndian);
  for (size_t i = 0; i < kTextSectionSize; ++i) {
    text.D8(i * 3);
  }
  elf.AddSection(".text", text, SHT_PROGBITS);
  elf.Finish();
  this->GetElfContents(elf);

  id_vector identifier(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier));

  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  EXPECT_EQ(expected_identifier_string, identifier_string);
}

TYPED_TEST(FileIDTest, BuildID) {
  const uint8_t kExpectedIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13};
  const string expected_identifier_string =
      this->get_file_id(kExpectedIdentifierBytes);

  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);
  Notes notes(kLittleEndian);
  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
                sizeof(kExpectedIdentifierBytes));
  elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
  elf.Finish();
  this->GetElfContents(elf);

  id_vector identifier(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier));
  EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());

  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  EXPECT_EQ(expected_identifier_string, identifier_string);
}

// Test that a build id note with fewer bytes than usual is handled.
TYPED_TEST(FileIDTest, BuildIDShort) {
  const uint8_t kExpectedIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03};
  const string expected_identifier_string =
      this->get_file_id(kExpectedIdentifierBytes);

  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);
  Notes notes(kLittleEndian);
  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
                sizeof(kExpectedIdentifierBytes));
  elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
  elf.Finish();
  this->GetElfContents(elf);

  id_vector identifier(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier));
  EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());

  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  EXPECT_EQ(expected_identifier_string, identifier_string);
}

// Test that a build id note with more bytes than usual is handled.
TYPED_TEST(FileIDTest, BuildIDLong) {
  const uint8_t kExpectedIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
  const string expected_identifier_string =
      this->get_file_id(kExpectedIdentifierBytes);

  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);
  Notes notes(kLittleEndian);
  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
                sizeof(kExpectedIdentifierBytes));
  elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
  elf.Finish();
  this->GetElfContents(elf);

  id_vector identifier(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier));
  EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());

  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  EXPECT_EQ(expected_identifier_string, identifier_string);
}

TYPED_TEST(FileIDTest, BuildIDPH) {
  const uint8_t kExpectedIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13};
  const string expected_identifier_string =
      this->get_file_id(kExpectedIdentifierBytes);

  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);
  Notes notes(kLittleEndian);
  notes.AddNote(0, "Linux",
                reinterpret_cast<const uint8_t*>("\0x42\0x02\0\0"), 4);
  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
                sizeof(kExpectedIdentifierBytes));
  int note_idx = elf.AddSection(".note", notes, SHT_NOTE);
  elf.AddSegment(note_idx, note_idx, PT_NOTE);
  elf.Finish();
  this->GetElfContents(elf);

  id_vector identifier(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier));
  EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());

  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  EXPECT_EQ(expected_identifier_string, identifier_string);
}

TYPED_TEST(FileIDTest, BuildIDMultiplePH) {
  const uint8_t kExpectedIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13};
  const string expected_identifier_string =
      this->get_file_id(kExpectedIdentifierBytes);

  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);
  Notes notes1(kLittleEndian);
  notes1.AddNote(0, "Linux",
                reinterpret_cast<const uint8_t*>("\0x42\0x02\0\0"), 4);
  Notes notes2(kLittleEndian);
  notes2.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
                 sizeof(kExpectedIdentifierBytes));
  int note1_idx = elf.AddSection(".note1", notes1, SHT_NOTE);
  int note2_idx = elf.AddSection(".note2", notes2, SHT_NOTE);
  elf.AddSegment(note1_idx, note1_idx, PT_NOTE);
  elf.AddSegment(note2_idx, note2_idx, PT_NOTE);
  elf.Finish();
  this->GetElfContents(elf);

  id_vector identifier(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier));
  EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());

  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  EXPECT_EQ(expected_identifier_string, identifier_string);
}

// Test to make sure two files with different text sections produce
// different hashes when not using a build id.
TYPED_TEST(FileIDTest, UniqueHashes) {
  {
    ELF elf1(EM_386, TypeParam::kClass, kLittleEndian);
    Section foo_1(kLittleEndian);
    PopulateSection(&foo_1, 32, 5);
    elf1.AddSection(".foo", foo_1, SHT_PROGBITS);
    Section text_1(kLittleEndian);
    PopulateSection(&text_1, 4096, 17);
    elf1.AddSection(".text", text_1, SHT_PROGBITS);
    elf1.Finish();
    this->GetElfContents(elf1);
  }

  id_vector identifier_1(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier_1));
  string identifier_string_1 =
      FileID::ConvertIdentifierToUUIDString(identifier_1);

  {
    ELF elf2(EM_386, TypeParam::kClass, kLittleEndian);
    Section text_2(kLittleEndian);
    Section foo_2(kLittleEndian);
    PopulateSection(&foo_2, 32, 5);
    elf2.AddSection(".foo", foo_2, SHT_PROGBITS);
    PopulateSection(&text_2, 4096, 31);
    elf2.AddSection(".text", text_2, SHT_PROGBITS);
    elf2.Finish();
    this->GetElfContents(elf2);
  }

  id_vector identifier_2(this->make_vector());
  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
                                                      identifier_2));
  string identifier_string_2 =
      FileID::ConvertIdentifierToUUIDString(identifier_2);

  EXPECT_NE(identifier_string_1, identifier_string_2);
}

TYPED_TEST(FileIDTest, ConvertIdentifierToString) {
  const uint8_t kIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
  const char* kExpected =
    "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";

  id_vector identifier(this->make_vector());
  identifier.insert(identifier.end(),
                    kIdentifierBytes,
                    kIdentifierBytes + sizeof(kIdentifierBytes));
  ASSERT_EQ(kExpected,
            FileID::ConvertIdentifierToString(identifier));
}
