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.
29 
30 // memory_range_unittest.cc: Unit tests for google_breakpad::MemoryRange.
31 
32 #include "breakpad_googletest_includes.h"
33 #include "common/memory_range.h"
34 
35 using google_breakpad::MemoryRange;
36 using testing::Message;
37 
38 namespace {
39 
40 const uint32_t kBuffer[10] = { 0 };
41 const size_t kBufferSize = sizeof(kBuffer);
42 const uint8_t* kBufferPointer = reinterpret_cast<const uint8_t*>(kBuffer);
43 
44 // Test vectors for verifying Covers, GetData, and Subrange.
45 const struct {
46   bool valid;
47   size_t offset;
48   size_t length;
49 } kSubranges[] = {
50   { true, 0, 0 },
51   { true, 0, 2 },
52   { true, 0, kBufferSize },
53   { true, 2, 0 },
54   { true, 2, 4 },
55   { true, 2, kBufferSize - 2 },
56   { true, kBufferSize - 1, 1 },
57   { false, kBufferSize, 0 },
58   { false, kBufferSize, static_cast<size_t>(-1) },
59   { false, kBufferSize + 1, 0 },
60   { false, static_cast<size_t>(-1), 2 },
61   { false, 1, kBufferSize },
62   { false, kBufferSize - 1, 2 },
63   { false, 0, static_cast<size_t>(-1) },
64   { false, 1, static_cast<size_t>(-1) },
65 };
66 const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]);
67 
68 // Test vectors for verifying GetArrayElement.
69 const struct {
70   size_t offset;
71   size_t size;
72   size_t index;
73   const void* const pointer;
74 } kElements[] = {
75   // Valid array elemenets
76   { 0, 1, 0, kBufferPointer },
77   { 0, 1, 1, kBufferPointer + 1 },
78   { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 },
79   { 0, 2, 1, kBufferPointer + 2 },
80   { 0, 4, 2, kBufferPointer + 8 },
81   { 0, 4, 9, kBufferPointer + 36 },
82   { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 },
83   // Invalid array elemenets
84   { 0, 1, kBufferSize, NULL },
85   { 0, 4, 10, NULL },
86   { kBufferSize - 1, 1, 1, NULL },
87   { kBufferSize - 1, 2, 0, NULL },
88   { kBufferSize, 1, 0, NULL },
89 };
90 const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]);
91 
92 }  // namespace
93 
TEST(MemoryRangeTest,DefaultConstructor)94 TEST(MemoryRangeTest, DefaultConstructor) {
95   MemoryRange range;
96   EXPECT_EQ(NULL, range.data());
97   EXPECT_EQ(0U, range.length());
98 }
99 
TEST(MemoryRangeTest,ConstructorWithDataAndLength)100 TEST(MemoryRangeTest, ConstructorWithDataAndLength) {
101   MemoryRange range(kBuffer, kBufferSize);
102   EXPECT_EQ(kBufferPointer, range.data());
103   EXPECT_EQ(kBufferSize, range.length());
104 }
105 
TEST(MemoryRangeTest,Reset)106 TEST(MemoryRangeTest, Reset) {
107   MemoryRange range;
108   range.Reset();
109   EXPECT_EQ(NULL, range.data());
110   EXPECT_EQ(0U, range.length());
111 
112   range.Set(kBuffer, kBufferSize);
113   EXPECT_EQ(kBufferPointer, range.data());
114   EXPECT_EQ(kBufferSize, range.length());
115 
116   range.Reset();
117   EXPECT_EQ(NULL, range.data());
118   EXPECT_EQ(0U, range.length());
119 }
120 
TEST(MemoryRangeTest,Set)121 TEST(MemoryRangeTest, Set) {
122   MemoryRange range;
123   range.Set(kBuffer, kBufferSize);
124   EXPECT_EQ(kBufferPointer, range.data());
125   EXPECT_EQ(kBufferSize, range.length());
126 
127   range.Set(NULL, 0);
128   EXPECT_EQ(NULL, range.data());
129   EXPECT_EQ(0U, range.length());
130 }
131 
TEST(MemoryRangeTest,SubrangeOfEmptyMemoryRange)132 TEST(MemoryRangeTest, SubrangeOfEmptyMemoryRange) {
133   MemoryRange range;
134   MemoryRange subrange = range.Subrange(0, 10);
135   EXPECT_EQ(NULL, subrange.data());
136   EXPECT_EQ(0U, subrange.length());
137 }
138 
TEST(MemoryRangeTest,SubrangeAndGetData)139 TEST(MemoryRangeTest, SubrangeAndGetData) {
140   MemoryRange range(kBuffer, kBufferSize);
141   for (size_t i = 0; i < kNumSubranges; ++i) {
142     bool valid = kSubranges[i].valid;
143     size_t sub_offset = kSubranges[i].offset;
144     size_t sub_length = kSubranges[i].length;
145     SCOPED_TRACE(Message() << "offset=" << sub_offset
146                  << ", length=" << sub_length);
147 
148     MemoryRange subrange = range.Subrange(sub_offset, sub_length);
149     if (valid) {
150       EXPECT_TRUE(range.Covers(sub_offset, sub_length));
151       EXPECT_EQ(kBufferPointer + sub_offset,
152                 range.GetData(sub_offset, sub_length));
153       EXPECT_EQ(kBufferPointer + sub_offset, subrange.data());
154       EXPECT_EQ(sub_length, subrange.length());
155     } else {
156       EXPECT_FALSE(range.Covers(sub_offset, sub_length));
157       EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length));
158       EXPECT_EQ(NULL, subrange.data());
159       EXPECT_EQ(0U, subrange.length());
160     }
161   }
162 }
163 
TEST(MemoryRangeTest,GetDataWithTemplateType)164 TEST(MemoryRangeTest, GetDataWithTemplateType) {
165   MemoryRange range(kBuffer, kBufferSize);
166   const char* char_pointer = range.GetData<char>(0);
167   EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer);
168   const int* int_pointer = range.GetData<int>(0);
169   EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer);
170 }
171 
TEST(MemoryRangeTest,GetArrayElement)172 TEST(MemoryRangeTest, GetArrayElement) {
173   MemoryRange range(kBuffer, kBufferSize);
174   for (size_t i = 0; i < kNumElements; ++i) {
175     size_t element_offset = kElements[i].offset;
176     size_t element_size = kElements[i].size;
177     unsigned element_index = kElements[i].index;
178     const void* const element_pointer = kElements[i].pointer;
179     SCOPED_TRACE(Message() << "offset=" << element_offset
180                  << ", size=" << element_size
181                  << ", index=" << element_index);
182     EXPECT_EQ(element_pointer, range.GetArrayElement(
183         element_offset, element_size, element_index));
184   }
185 }
186 
TEST(MemoryRangeTest,GetArrayElmentWithTemplateType)187 TEST(MemoryRangeTest, GetArrayElmentWithTemplateType) {
188   MemoryRange range(kBuffer, kBufferSize);
189   const char* char_pointer = range.GetArrayElement<char>(0, 0);
190   EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer);
191   const int* int_pointer = range.GetArrayElement<int>(0, 0);
192   EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer);
193 }
194