1 // Copyright 2015 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <stdint.h> 6 7 #include <vector> 8 9 #include "buffer_writer.h" 10 #include "compat/test.h" 11 12 namespace quipper { 13 14 // Move the cursor around and make sure the offset is properly set each time. 15 TEST(BufferWriterTest, MoveOffset) { 16 std::vector<uint8_t> buffer(1000); 17 18 BufferWriter writer(buffer.data(), buffer.size()); 19 EXPECT_EQ(0, writer.Tell()); 20 EXPECT_EQ(buffer.size(), writer.size()); 21 22 // Move the write cursor around. 23 writer.SeekSet(100); 24 EXPECT_EQ(100, writer.Tell()); 25 writer.SeekSet(900); 26 EXPECT_EQ(900, writer.Tell()); 27 writer.SeekSet(500); 28 EXPECT_EQ(500, writer.Tell()); 29 30 // The cursor can be set to past the end of the buffer, but can't perform any 31 // write operations there. 32 writer.SeekSet(1200); 33 EXPECT_EQ(1200, writer.Tell()); 34 int dummy = 0; 35 EXPECT_FALSE(writer.WriteData(&dummy, sizeof(dummy))); 36 } 37 38 // Make sure that the writer can handle a write size of zero. 39 TEST(BufferWriterTest, WriteZeroBytes) { 40 std::vector<uint8_t> output(10); 41 BufferWriter writer(output.data(), output.size()); 42 writer.SeekSet(5); 43 EXPECT_TRUE(writer.WriteData(NULL, 0)); 44 // Make sure the write pointer hasn't moved. 45 EXPECT_EQ(5, writer.Tell()); 46 } 47 48 // Write a chunk of data to the output buffer. 49 TEST(BufferWriterTest, WriteSingleChunk) { 50 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 51 std::vector<uint8_t> output(kInputData.size()); 52 BufferWriter writer(output.data(), output.size()); 53 54 EXPECT_TRUE(writer.WriteData(kInputData.data(), kInputData.size())); 55 EXPECT_EQ(output.size(), writer.Tell()); 56 57 // Compare input and output data, converting the latter to a string for 58 // clarity of error messages. 59 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 60 } 61 62 // Test the WriteDataValue() function, which is a wrapper around WriteData(). 63 TEST(BufferWriterTest, WriteDataValue) { 64 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 65 std::vector<uint8_t> output(kInputData.size()); 66 BufferWriter writer(output.data(), output.size()); 67 68 EXPECT_TRUE( 69 writer.WriteDataValue(kInputData.data(), kInputData.size(), "data")); 70 EXPECT_EQ(output.size(), writer.Tell()); 71 72 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 73 } 74 75 // Write in all data from the input buffer in multiple chunks, in order. 76 TEST(BufferWriterTest, WriteMultipleChunks) { 77 // This string is 26 characters long. 78 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 79 80 std::vector<uint8_t> output(kInputData.size()); 81 BufferWriter writer(output.data(), output.size()); 82 83 // Write all the data in multiple operations. Make sure the cursor is updated. 84 EXPECT_TRUE(writer.WriteData(kInputData.data() + writer.Tell(), 10)); 85 EXPECT_EQ(10, writer.Tell()); 86 EXPECT_TRUE(writer.WriteData(kInputData.data() + writer.Tell(), 5)); 87 EXPECT_EQ(15, writer.Tell()); 88 EXPECT_TRUE(writer.WriteData(kInputData.data() + writer.Tell(), 5)); 89 EXPECT_EQ(20, writer.Tell()); 90 EXPECT_TRUE(writer.WriteData(kInputData.data() + writer.Tell(), 6)); 91 EXPECT_EQ(26, writer.Tell()); 92 93 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 94 } 95 96 // Write all data from the input buffer in multiple chunks, but not in order. 97 TEST(BufferWriterTest, WriteWithJumps) { 98 // This string contains four parts, each 10 characters long. 99 const string kInputData = 100 "0:abcdefg;" 101 "1:hijklmn;" 102 "2:opqrstu;" 103 "3:vwxyzABC"; 104 105 std::vector<uint8_t> output(kInputData.size()); 106 BufferWriter writer(output.data(), output.size()); 107 108 writer.SeekSet(20); 109 EXPECT_TRUE(writer.WriteData(kInputData.data() + 20, 10)); 110 EXPECT_EQ(30, writer.Tell()); 111 EXPECT_EQ("2:opqrstu;", string(output.begin() + 20, output.begin() + 30)); 112 113 writer.SeekSet(10); 114 EXPECT_TRUE(writer.WriteData(kInputData.data() + 10, 10)); 115 EXPECT_EQ(20, writer.Tell()); 116 EXPECT_EQ("1:hijklmn;", string(output.begin() + 10, output.begin() + 20)); 117 118 writer.SeekSet(30); 119 EXPECT_TRUE(writer.WriteData(kInputData.data() + 30, 10)); 120 EXPECT_EQ(40, writer.Tell()); 121 EXPECT_EQ("3:vwxyzABC", string(output.begin() + 30, output.begin() + 40)); 122 123 writer.SeekSet(0); 124 EXPECT_TRUE(writer.WriteData(kInputData.data(), 10)); 125 EXPECT_EQ(10, writer.Tell()); 126 EXPECT_EQ("0:abcdefg;", string(output.begin(), output.begin() + 10)); 127 } 128 129 // Test writing past the end of the buffer. 130 TEST(BufferWriterTest, WritePastEndOfData) { 131 // This string is 26 characters long. 132 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 133 std::vector<uint8_t> output(kInputData.size()); 134 BufferWriter writer(output.data(), output.size()); 135 136 // Must not be able to write past the end of the buffer. 137 writer.SeekSet(0); 138 EXPECT_FALSE(writer.WriteData(kInputData.data() + writer.Tell(), 30)); 139 // The write pointer should not have moved. 140 EXPECT_EQ(0, writer.Tell()); 141 142 // Should still be able to write within the bounds of the buffer, despite the 143 // out-of-bounds write earlier. 144 EXPECT_TRUE(writer.WriteData(kInputData.data() + writer.Tell(), 13)); 145 EXPECT_EQ(13, writer.Tell()); 146 147 // Now attempt another write past the end of the buffer, but starting from the 148 // ending position of the previous write operation. 149 EXPECT_FALSE(writer.WriteData(kInputData.data() + writer.Tell(), 20)); 150 // The write pointer should be unchanged. 151 EXPECT_EQ(13, writer.Tell()); 152 153 // Write the rest of the data and make sure it matches the input. 154 EXPECT_TRUE(writer.WriteData(kInputData.data() + writer.Tell(), 13)); 155 EXPECT_EQ(26, writer.Tell()); 156 157 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 158 } 159 160 // Test string writes. 161 TEST(BufferWriterTest, WriteString) { 162 // Construct an input string. 163 string input("The quick brown fox jumps over the lazy dog."); 164 165 // Write the full string. 166 std::vector<char> full_output(input.size()); 167 BufferWriter full_writer(full_output.data(), full_output.size()); 168 EXPECT_TRUE(full_writer.WriteString(input, input.size())); 169 EXPECT_EQ(input.size(), full_writer.Tell()); 170 // There is no null pointer at the end of the output buffer, so create a 171 // string out of it using the known length of the input string. 172 EXPECT_EQ(input, string(full_output.data(), input.size())); 173 174 // Write the full string plus the null pointer. 175 std::vector<char> full_null_output(input.size() + 1); 176 BufferWriter full_null_writer(full_null_output.data(), 177 full_null_output.size()); 178 EXPECT_TRUE(full_null_writer.WriteString(input, input.size() + 1)); 179 EXPECT_EQ(input.size() + 1, full_null_writer.Tell()); 180 // The null pointer should have been written. It should determine the end of 181 // the string. 182 EXPECT_EQ(input, string(full_null_output.data())); 183 184 // Write the first half of the string. 185 std::vector<char> half_output(input.size() / 2); 186 BufferWriter half_writer(half_output.data(), half_output.size()); 187 EXPECT_TRUE(half_writer.WriteString(input, input.size() / 2)); 188 EXPECT_EQ(input.size() / 2, half_writer.Tell()); 189 // Null terminator is not guaranteed, so use the input string size to limit 190 // the output string during comparison. 191 EXPECT_EQ(input.substr(0, input.size() / 2), 192 string(half_output.data(), input.size() / 2)); 193 194 // Attempt to write past the end of the buffer. Should fail. 195 std::vector<char> past_end_buffer(input.size()); 196 BufferWriter past_end_writer(past_end_buffer.data(), past_end_buffer.size()); 197 EXPECT_FALSE(past_end_writer.WriteString(input, input.size() + 2)); 198 199 // Write string with some extra padding. 200 std::vector<char> extra_padding_output(input.size() + 10); 201 BufferWriter vector_writer(extra_padding_output.data(), 202 extra_padding_output.size()); 203 EXPECT_TRUE(vector_writer.WriteString(input, extra_padding_output.size())); 204 // The writer should have written both the string data and padding bytes. 205 EXPECT_EQ(extra_padding_output.size(), vector_writer.Tell()); 206 // But the string should still be null-terminated. 207 EXPECT_EQ(input, extra_padding_output.data()); 208 } 209 210 // Writes data to a buffer and verifies that the buffer has not been modified 211 // beyond the writable boundaries. 212 TEST(BufferWriterTest, NoWritingOutOfBounds) { 213 // A sentinel value that fills memory to detect when that section of memory is 214 // overwritten. If the memory shows another value, it means it has been 215 // overwritten. 216 const uint8_t kUnwrittenValue = 0xaa; 217 218 std::vector<uint8_t> buffer(1000, kUnwrittenValue); 219 // Only write to the range [100, 900). 220 BufferWriter writer(buffer.data() + 100, 800); 221 222 // Create some input data that's filled with zeroes. Write this to the buffer. 223 std::vector<uint8_t> input(800, 0); 224 EXPECT_TRUE(writer.WriteData(input.data(), input.size())); 225 EXPECT_EQ(input.size(), writer.Tell()); 226 227 // Check that the data was written to the writable part of the buffer. 228 EXPECT_EQ(input, 229 std::vector<uint8_t>(buffer.begin() + 100, buffer.begin() + 900)); 230 231 // Now make sure that the other parts of the buffer haven't been overwritten. 232 const std::vector<uint8_t> expected_unwritten_part(100, kUnwrittenValue); 233 EXPECT_EQ(expected_unwritten_part, 234 std::vector<uint8_t>(buffer.begin(), buffer.begin() + 100)); 235 EXPECT_EQ(expected_unwritten_part, 236 std::vector<uint8_t>(buffer.begin() + 900, buffer.begin() + 1000)); 237 } 238 239 // Writes a string to a buffer and verifies that the buffer has not been 240 // modified beyond the writable boundaries. 241 TEST(BufferWriterTest, NoWritingStringOutOfBounds) { 242 // Construct an input string. 243 string input("This line is forty characters long....."); 244 245 // A sentinel value that fills memory to detect when that section of memory is 246 // overwritten. If the memory shows another value, it means it has been 247 // overwritten. 248 const uint8_t kUnwrittenValue = 0xaa; 249 std::vector<char> buffer(100, kUnwrittenValue); 250 251 // Only write to the range [20, 61). This includes enough space for the string 252 // and the null terminator. Make sure the string is short enough that it fits 253 // inside the buffer and leaves at least one byte of extra space at the end, 254 // beyond the null terminator. 255 ASSERT_LT(input.size() + 1, buffer.size() - 20); 256 BufferWriter writer(buffer.data() + 20, input.size() + 1); 257 258 // Write the string plus null terminator, and verify that it was written. 259 EXPECT_TRUE(writer.WriteString(input, input.size() + 1)); 260 EXPECT_EQ(input, buffer.data() + 20); 261 EXPECT_EQ(input.size() + 1, writer.Tell()); 262 263 // Now make sure that the other parts of the buffer haven't been overwritten. 264 EXPECT_EQ(std::vector<char>(20, kUnwrittenValue), 265 std::vector<char>(buffer.begin(), buffer.begin() + 20)); 266 // There are 39 bytes between offset 61 (end of the string contents) and the 267 // end of the buffer. 268 EXPECT_EQ(std::vector<char>(39, kUnwrittenValue), 269 std::vector<char>(buffer.begin() + 61, buffer.end())); 270 } 271 272 } // namespace quipper 273