toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf_unittest.cc

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 // Copyright (c) 2011 Google Inc.
     2 // All rights reserved.
     3 //
     4 // Redistribution and use in source and binary forms, with or without
     5 // modification, are permitted provided that the following conditions are
     6 // met:
     7 //
     8 //     * Redistributions of source code must retain the above copyright
     9 // notice, this list of conditions and the following disclaimer.
    10 //     * Redistributions in binary form must reproduce the above
    11 // copyright notice, this list of conditions and the following disclaimer
    12 // in the documentation and/or other materials provided with the
    13 // distribution.
    14 //     * Neither the name of Google Inc. nor the names of its
    15 // contributors may be used to endorse or promote products derived from
    16 // this software without specific prior written permission.
    17 //
    18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    30 // Original author: Ted Mielczarek <ted.mielczarek@gmail.com>
    32 // synth_elf_unittest.cc:
    33 // Unittests for google_breakpad::synth_elf::ELF
    35 #include <elf.h>
    37 #include "breakpad_googletest_includes.h"
    38 #include "common/linux/elfutils.h"
    39 #include "common/linux/synth_elf.h"
    40 #include "common/using_std_string.h"
    42 using google_breakpad::ElfClass32;
    43 using google_breakpad::ElfClass64;
    44 using google_breakpad::synth_elf::ELF;
    45 using google_breakpad::synth_elf::Notes;
    46 using google_breakpad::synth_elf::Section;
    47 using google_breakpad::synth_elf::StringTable;
    48 using google_breakpad::synth_elf::SymbolTable;
    49 using google_breakpad::test_assembler::Endianness;
    50 using google_breakpad::test_assembler::kBigEndian;
    51 using google_breakpad::test_assembler::kLittleEndian;
    52 using google_breakpad::test_assembler::Label;
    53 using ::testing::Test;
    54 using ::testing::Types;
    56 class StringTableTest : public Test {
    57 public:
    58   StringTableTest() : table(kLittleEndian) {}
    60   StringTable table;
    61 };
    63 TEST_F(StringTableTest, Empty) {
    64   EXPECT_EQ(1U, table.Size());
    65   string contents;
    66   ASSERT_TRUE(table.GetContents(&contents));
    67   const char* kExpectedContents = "\0";
    68   EXPECT_EQ(0, memcmp(kExpectedContents,
    69                       contents.c_str(),
    70                       contents.size()));
    71   ASSERT_TRUE(table.empty_string.IsKnownConstant());
    72   EXPECT_EQ(0U, table.empty_string.Value());
    73 }
    75 TEST_F(StringTableTest, Basic) {
    76   const string s1("table fills with strings");
    77   const string s2("offsets preserved as labels");
    78   const string s3("verified with tests");
    79   const char* kExpectedContents = 
    80     "\0table fills with strings\0"
    81     "offsets preserved as labels\0"
    82     "verified with tests\0";
    83   Label l1(table.Add(s1));
    84   Label l2(table.Add(s2));
    85   Label l3(table.Add(s3));
    86   string contents;
    87   ASSERT_TRUE(table.GetContents(&contents));
    88   EXPECT_EQ(0, memcmp(kExpectedContents,
    89                       contents.c_str(),
    90                       contents.size()));
    91   // empty_string is at zero, other strings start at 1.
    92   ASSERT_TRUE(l1.IsKnownConstant());
    93   EXPECT_EQ(1U, l1.Value());
    94   // Each string has an extra byte for a trailing null.
    95   EXPECT_EQ(1 + s1.length() + 1, l2.Value());
    96   EXPECT_EQ(1 + s1.length() + 1 + s2.length() + 1, l3.Value());
    97 }
    99 TEST_F(StringTableTest, Duplicates) {
   100   const string s1("string 1");
   101   const string s2("string 2");
   102   const string s3("");
   103   const char* kExpectedContents = "\0string 1\0string 2\0";
   104   Label l1(table.Add(s1));
   105   Label l2(table.Add(s2));
   106   // Adding strings twice should return the same Label.
   107   Label l3(table.Add(s3));
   108   Label l4(table.Add(s2));
   109   string contents;
   110   ASSERT_TRUE(table.GetContents(&contents));
   111   EXPECT_EQ(0, memcmp(kExpectedContents,
   112                       contents.c_str(),
   113                       contents.size()));
   114   EXPECT_EQ(0U, table.empty_string.Value());
   115   EXPECT_EQ(table.empty_string.Value(), l3.Value());
   116   EXPECT_EQ(l2.Value(), l4.Value());
   117 }
   119 class SymbolTableTest : public Test {};
   121 TEST_F(SymbolTableTest, Simple32) {
   122   StringTable table(kLittleEndian);
   123   SymbolTable syms(kLittleEndian, 4, table);
   125   const string kFuncName1 = "superfunc";
   126   const uint32_t kFuncAddr1 = 0x10001000;
   127   const uint32_t kFuncSize1 = 0x10;
   128   const string kFuncName2 = "awesomefunc";
   129   const uint32_t kFuncAddr2 = 0x20002000;
   130   const uint32_t kFuncSize2 = 0x2f;
   131   const string kFuncName3 = "megafunc";
   132   const uint32_t kFuncAddr3 = 0x30003000;
   133   const uint32_t kFuncSize3 = 0x3c;
   135   syms.AddSymbol(kFuncName1, kFuncAddr1, kFuncSize1,
   136                  ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
   137                  SHN_UNDEF + 1);
   138   syms.AddSymbol(kFuncName2, kFuncAddr2, kFuncSize2,
   139                  ELF32_ST_INFO(STB_LOCAL, STT_FUNC),
   140                  SHN_UNDEF + 2);
   141   syms.AddSymbol(kFuncName3, kFuncAddr3, kFuncSize3,
   142                  ELF32_ST_INFO(STB_LOCAL, STT_FUNC),
   143                  SHN_UNDEF + 3);
   145   const char kExpectedStringTable[] = "\0superfunc\0awesomefunc\0megafunc";
   146   const size_t kExpectedStringTableSize = sizeof(kExpectedStringTable);
   147   EXPECT_EQ(kExpectedStringTableSize, table.Size());
   148   string table_contents;
   149   table.GetContents(&table_contents);
   150   EXPECT_EQ(0, memcmp(kExpectedStringTable,
   151                       table_contents.c_str(),
   152                       table_contents.size()));
   154   const uint8_t kExpectedSymbolContents[] = {
   155     // Symbol 1
   156     0x01, 0x00, 0x00, 0x00, // name
   157     0x00, 0x10, 0x00, 0x10, // value
   158     0x10, 0x00, 0x00, 0x00, // size
   159     ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), // info
   160     0x00, // other
   161     0x01, 0x00, // shndx
   162     // Symbol 2
   163     0x0B, 0x00, 0x00, 0x00, // name
   164     0x00, 0x20, 0x00, 0x20, // value
   165     0x2f, 0x00, 0x00, 0x00, // size
   166     ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info
   167     0x00, // other
   168     0x02, 0x00, // shndx
   169     // Symbol 3
   170     0x17, 0x00, 0x00, 0x00, // name
   171     0x00, 0x30, 0x00, 0x30, // value
   172     0x3c, 0x00, 0x00, 0x00, // size
   173     ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info
   174     0x00, // other
   175     0x03, 0x00, // shndx
   176   };
   177   const size_t kExpectedSymbolSize = sizeof(kExpectedSymbolContents);
   178   EXPECT_EQ(kExpectedSymbolSize, syms.Size());
   180   string symbol_contents;
   181   syms.GetContents(&symbol_contents);
   182   EXPECT_EQ(0, memcmp(kExpectedSymbolContents,
   183                       symbol_contents.c_str(),
   184                       symbol_contents.size()));
   185 }
   187 template<typename ElfClass>
   188 class BasicElf : public Test {};
   190 // Doesn't seem worthwhile writing the tests to be endian-independent
   191 // when they're unlikely to ever be run on big-endian systems.
   192 #if defined(__i386__) || defined(__x86_64__)
   194 typedef Types<ElfClass32, ElfClass64> ElfClasses;
   196 TYPED_TEST_CASE(BasicElf, ElfClasses);
   198 TYPED_TEST(BasicElf, EmptyLE) {
   199   typedef typename TypeParam::Ehdr Ehdr;
   200   typedef typename TypeParam::Phdr Phdr;
   201   typedef typename TypeParam::Shdr Shdr;
   202   const size_t kStringTableSize = sizeof("\0.shstrtab");
   203   const size_t kStringTableAlign = 4 - kStringTableSize % 4;
   204   const size_t kExpectedSize = sizeof(Ehdr) +
   205     // Two sections, SHT_NULL + the section header string table.
   206     2 * sizeof(Shdr) +
   207     kStringTableSize + kStringTableAlign;
   209   // It doesn't really matter that the machine type is right for the class.
   210   ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
   211   elf.Finish();
   212   EXPECT_EQ(kExpectedSize, elf.Size());
   214   string contents;
   215   ASSERT_TRUE(elf.GetContents(&contents));
   216   ASSERT_EQ(kExpectedSize, contents.size());
   217   const Ehdr* header =
   218     reinterpret_cast<const Ehdr*>(contents.data());
   219   const uint8_t kIdent[] = {
   220     ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
   221     TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
   222     0, 0, 0, 0, 0, 0, 0, 0
   223   };
   224   EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent)));
   225   EXPECT_EQ(ET_EXEC, header->e_type);
   226   EXPECT_EQ(EM_386, header->e_machine);
   227   EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version);
   228   EXPECT_EQ(0U, header->e_entry);
   229   EXPECT_EQ(0U, header->e_phoff);
   230   EXPECT_EQ(sizeof(Ehdr) + kStringTableSize + kStringTableAlign,
   231             header->e_shoff);
   232   EXPECT_EQ(0U, header->e_flags);
   233   EXPECT_EQ(sizeof(Ehdr), header->e_ehsize);
   234   EXPECT_EQ(sizeof(Phdr), header->e_phentsize);
   235   EXPECT_EQ(0, header->e_phnum);
   236   EXPECT_EQ(sizeof(Shdr), header->e_shentsize);
   237   EXPECT_EQ(2, header->e_shnum);
   238   EXPECT_EQ(1, header->e_shstrndx);
   240   const Shdr* shdr =
   241     reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff);
   242   EXPECT_EQ(0U, shdr[0].sh_name);
   243   EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type);
   244   EXPECT_EQ(0U, shdr[0].sh_flags);
   245   EXPECT_EQ(0U, shdr[0].sh_addr);
   246   EXPECT_EQ(0U, shdr[0].sh_offset);
   247   EXPECT_EQ(0U, shdr[0].sh_size);
   248   EXPECT_EQ(0U, shdr[0].sh_link);
   249   EXPECT_EQ(0U, shdr[0].sh_info);
   250   EXPECT_EQ(0U, shdr[0].sh_addralign);
   251   EXPECT_EQ(0U, shdr[0].sh_entsize);
   253   EXPECT_EQ(1U, shdr[1].sh_name);
   254   EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[1].sh_type);
   255   EXPECT_EQ(0U, shdr[1].sh_flags);
   256   EXPECT_EQ(0U, shdr[1].sh_addr);
   257   EXPECT_EQ(sizeof(Ehdr), shdr[1].sh_offset);
   258   EXPECT_EQ(kStringTableSize, shdr[1].sh_size);
   259   EXPECT_EQ(0U, shdr[1].sh_link);
   260   EXPECT_EQ(0U, shdr[1].sh_info);
   261   EXPECT_EQ(0U, shdr[1].sh_addralign);
   262   EXPECT_EQ(0U, shdr[1].sh_entsize);
   263 }
   265 TYPED_TEST(BasicElf, BasicLE) {
   266   typedef typename TypeParam::Ehdr Ehdr;
   267   typedef typename TypeParam::Phdr Phdr;
   268   typedef typename TypeParam::Shdr Shdr;
   269   const size_t kStringTableSize = sizeof("\0.text\0.bss\0.shstrtab");
   270   const size_t kStringTableAlign = 4 - kStringTableSize % 4;
   271   const size_t kExpectedSize = sizeof(Ehdr) +
   272     // Four sections, SHT_NULL + the section header string table +
   273     // 4096 bytes of the size-aligned .text section + one program header.
   274     sizeof(Phdr) + 4 * sizeof(Shdr) + 4096 +
   275     kStringTableSize + kStringTableAlign;
   277   // It doesn't really matter that the machine type is right for the class.
   278   ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
   279   Section text(kLittleEndian);
   280   text.Append(4094, 0);
   281   int text_idx = elf.AddSection(".text", text, SHT_PROGBITS);
   282   Section bss(kLittleEndian);
   283   bss.Append(16, 0);
   284   int bss_idx = elf.AddSection(".bss", bss, SHT_NOBITS);
   285   elf.AddSegment(text_idx, bss_idx, PT_LOAD);
   286   elf.Finish();
   287   EXPECT_EQ(kExpectedSize, elf.Size());
   289   string contents;
   290   ASSERT_TRUE(elf.GetContents(&contents));
   291   ASSERT_EQ(kExpectedSize, contents.size());
   292   const Ehdr* header =
   293     reinterpret_cast<const Ehdr*>(contents.data());
   294   const uint8_t kIdent[] = {
   295     ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
   296     TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
   297     0, 0, 0, 0, 0, 0, 0, 0
   298   };
   299   EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent)));
   300   EXPECT_EQ(ET_EXEC, header->e_type);
   301   EXPECT_EQ(EM_386, header->e_machine);
   302   EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version);
   303   EXPECT_EQ(0U, header->e_entry);
   304   EXPECT_EQ(sizeof(Ehdr), header->e_phoff);
   305   EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096 + kStringTableSize +
   306             kStringTableAlign, header->e_shoff);
   307   EXPECT_EQ(0U, header->e_flags);
   308   EXPECT_EQ(sizeof(Ehdr), header->e_ehsize);
   309   EXPECT_EQ(sizeof(Phdr), header->e_phentsize);
   310   EXPECT_EQ(1, header->e_phnum);
   311   EXPECT_EQ(sizeof(Shdr), header->e_shentsize);
   312   EXPECT_EQ(4, header->e_shnum);
   313   EXPECT_EQ(3, header->e_shstrndx);
   315   const Shdr* shdr =
   316     reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff);
   317   EXPECT_EQ(0U, shdr[0].sh_name);
   318   EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type);
   319   EXPECT_EQ(0U, shdr[0].sh_flags);
   320   EXPECT_EQ(0U, shdr[0].sh_addr);
   321   EXPECT_EQ(0U, shdr[0].sh_offset);
   322   EXPECT_EQ(0U, shdr[0].sh_size);
   323   EXPECT_EQ(0U, shdr[0].sh_link);
   324   EXPECT_EQ(0U, shdr[0].sh_info);
   325   EXPECT_EQ(0U, shdr[0].sh_addralign);
   326   EXPECT_EQ(0U, shdr[0].sh_entsize);
   328   EXPECT_EQ(1U, shdr[1].sh_name);
   329   EXPECT_EQ(static_cast<unsigned int>(SHT_PROGBITS), shdr[1].sh_type);
   330   EXPECT_EQ(0U, shdr[1].sh_flags);
   331   EXPECT_EQ(0U, shdr[1].sh_addr);
   332   EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), shdr[1].sh_offset);
   333   EXPECT_EQ(4094U, shdr[1].sh_size);
   334   EXPECT_EQ(0U, shdr[1].sh_link);
   335   EXPECT_EQ(0U, shdr[1].sh_info);
   336   EXPECT_EQ(0U, shdr[1].sh_addralign);
   337   EXPECT_EQ(0U, shdr[1].sh_entsize);
   339   EXPECT_EQ(sizeof("\0.text"), shdr[2].sh_name);
   340   EXPECT_EQ(static_cast<unsigned int>(SHT_NOBITS), shdr[2].sh_type);
   341   EXPECT_EQ(0U, shdr[2].sh_flags);
   342   EXPECT_EQ(0U, shdr[2].sh_addr);
   343   EXPECT_EQ(0U, shdr[2].sh_offset);
   344   EXPECT_EQ(16U, shdr[2].sh_size);
   345   EXPECT_EQ(0U, shdr[2].sh_link);
   346   EXPECT_EQ(0U, shdr[2].sh_info);
   347   EXPECT_EQ(0U, shdr[2].sh_addralign);
   348   EXPECT_EQ(0U, shdr[2].sh_entsize);
   350   EXPECT_EQ(sizeof("\0.text\0.bss"), shdr[3].sh_name);
   351   EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[3].sh_type);
   352   EXPECT_EQ(0U, shdr[3].sh_flags);
   353   EXPECT_EQ(0U, shdr[3].sh_addr);
   354   EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096, shdr[3].sh_offset);
   355   EXPECT_EQ(kStringTableSize, shdr[3].sh_size);
   356   EXPECT_EQ(0U, shdr[3].sh_link);
   357   EXPECT_EQ(0U, shdr[3].sh_info);
   358   EXPECT_EQ(0U, shdr[3].sh_addralign);
   359   EXPECT_EQ(0U, shdr[3].sh_entsize);
   361   const Phdr* phdr =
   362     reinterpret_cast<const Phdr*>(contents.data() + header->e_phoff);
   363   EXPECT_EQ(static_cast<unsigned int>(PT_LOAD), phdr->p_type);
   364   EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), phdr->p_offset);
   365   EXPECT_EQ(0U, phdr->p_vaddr);
   366   EXPECT_EQ(0U, phdr->p_paddr);
   367   EXPECT_EQ(4096U, phdr->p_filesz);
   368   EXPECT_EQ(4096U + 16U, phdr->p_memsz);
   369   EXPECT_EQ(0U, phdr->p_flags);
   370   EXPECT_EQ(0U, phdr->p_align);
   371 }
   373 class ElfNotesTest : public Test {};
   375 TEST_F(ElfNotesTest, Empty) {
   376   Notes notes(kLittleEndian);
   377   string contents;
   378   ASSERT_TRUE(notes.GetContents(&contents));
   379   EXPECT_EQ(0U, contents.size());
   380 }
   382 TEST_F(ElfNotesTest, Notes) {
   383   Notes notes(kLittleEndian);
   384   notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t *>("\x42\x02\0\0"),
   385                 4);
   386   notes.AddNote(2, "a", reinterpret_cast<const uint8_t *>("foobar"),
   387                 sizeof("foobar") - 1);
   389   const uint8_t kExpectedNotesContents[] = {
   390     // Note 1
   391     0x06, 0x00, 0x00, 0x00, // name size, including terminating zero
   392     0x04, 0x00, 0x00, 0x00, // desc size
   393     0x01, 0x00, 0x00, 0x00, // type
   394     'L', 'i', 'n', 'u', 'x', 0x00, 0x00, 0x00, // padded "Linux"
   395     0x42, 0x02, 0x00, 0x00, // desc
   396     // Note 2
   397     0x02, 0x00, 0x00, 0x00, // name size
   398     0x06, 0x00, 0x00, 0x00, // desc size
   399     0x02, 0x00, 0x00, 0x00, // type
   400     'a',  0x00, 0x00, 0x00, // padded "a"
   401     'f', 'o', 'o', 'b', 'a', 'r', 0x00, 0x00, // padded "foobar"
   402   };
   403   const size_t kExpectedNotesSize = sizeof(kExpectedNotesContents);
   404   EXPECT_EQ(kExpectedNotesSize, notes.Size());
   406   string notes_contents;
   407   ASSERT_TRUE(notes.GetContents(&notes_contents));
   408   EXPECT_EQ(0, memcmp(kExpectedNotesContents,
   409                       notes_contents.data(),
   410                       notes_contents.size()));
   411 }
   413 #endif  // defined(__i386__) || defined(__x86_64__)

mercurial