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 <algorithm> 8 #include <vector> 9 10 #include "buffer_reader.h" 11 #include "compat/string.h" 12 #include "compat/test.h" 13 14 namespace quipper { 15 16 // Move the cursor around and make sure the offset is properly set each time. 17 TEST(BufferReaderTest, MoveOffset) { 18 const std::vector<uint8_t> input(1000); 19 BufferReader reader(input.data(), input.size()); 20 21 // Make sure the reader was properly created. 22 EXPECT_EQ(input.size(), reader.size()); 23 EXPECT_EQ(0, reader.Tell()); 24 25 // Move the read cursor around. 26 reader.SeekSet(100); 27 EXPECT_EQ(100, reader.Tell()); 28 reader.SeekSet(900); 29 EXPECT_EQ(900, reader.Tell()); 30 reader.SeekSet(500); 31 EXPECT_EQ(500, reader.Tell()); 32 33 // The cursor can be set to past the end of the buffer, but can't perform any 34 // read operations there. 35 reader.SeekSet(1200); 36 EXPECT_EQ(1200, reader.Tell()); 37 int dummy; 38 EXPECT_FALSE(reader.ReadData(sizeof(dummy), &dummy)); 39 } 40 41 // Make sure that the reader can handle a read size of zero. 42 TEST(BufferReaderTest, ReadZeroBytes) { 43 const std::vector<uint8_t> input(10); 44 BufferReader reader(input.data(), input.size()); 45 46 // Move to some location within the buffer. 47 reader.SeekSet(5); 48 EXPECT_TRUE(reader.ReadData(0, NULL)); 49 50 // Make sure the read pointer hasn't moved. 51 EXPECT_EQ(5, reader.Tell()); 52 } 53 54 // Read in all data from the input buffer at once. 55 TEST(BufferReaderTest, ReadSingleChunk) { 56 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 57 BufferReader reader(kInputData.data(), kInputData.size()); 58 59 std::vector<uint8_t> output(kInputData.size()); 60 EXPECT_TRUE(reader.ReadData(output.size(), output.data())); 61 EXPECT_EQ(output.size(), reader.Tell()); 62 // Compare input and output data, converting the latter to a string for 63 // clarity of error messages. 64 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 65 } 66 67 // Test the ReadDataValue() function, which is a wrapper around ReadData(). 68 TEST(BufferReaderTest, ReadDataValue) { 69 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 70 BufferReader reader(kInputData.data(), kInputData.size()); 71 72 std::vector<uint8_t> output(kInputData.size()); 73 EXPECT_TRUE(reader.ReadDataValue(output.size(), "data", output.data())); 74 EXPECT_EQ(output.size(), reader.Tell()); 75 76 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 77 } 78 79 // Read in all data from the input buffer in multiple chunks, in order. 80 TEST(BufferReaderTest, ReadMultipleChunks) { 81 // This string is 26 characters long. 82 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 83 BufferReader reader(kInputData.data(), kInputData.size()); 84 85 // Make sure the cursor is updated after each read. 86 std::vector<uint8_t> output(kInputData.size()); 87 EXPECT_TRUE(reader.ReadData(10, output.data() + reader.Tell())); 88 EXPECT_EQ(10, reader.Tell()); 89 EXPECT_TRUE(reader.ReadData(5, output.data() + reader.Tell())); 90 EXPECT_EQ(15, reader.Tell()); 91 EXPECT_TRUE(reader.ReadData(5, output.data() + reader.Tell())); 92 EXPECT_EQ(20, reader.Tell()); 93 EXPECT_TRUE(reader.ReadData(6, output.data() + reader.Tell())); 94 EXPECT_EQ(26, reader.Tell()); 95 96 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 97 } 98 99 // Read in all data from the input buffer in multiple chunks, but not in order. 100 TEST(BufferReaderTest, ReadWithJumps) { 101 // This string contains four parts, each 10 characters long. 102 const string kInputData = 103 "0:abcdefg;" 104 "1:hijklmn;" 105 "2:opqrstu;" 106 "3:vwxyzABC"; 107 BufferReader reader(kInputData.data(), kInputData.size()); 108 109 // Read the data in multiple operations, but not in order. Overwrite the 110 // previously read data in the destination buffer during each read. 111 std::vector<uint8_t> output(10); 112 113 reader.SeekSet(20); 114 EXPECT_TRUE(reader.ReadData(10, output.data())); 115 EXPECT_EQ(30, reader.Tell()); 116 EXPECT_EQ("2:opqrstu;", string(output.begin(), output.end())); 117 118 reader.SeekSet(10); 119 EXPECT_TRUE(reader.ReadData(10, output.data())); 120 EXPECT_EQ(20, reader.Tell()); 121 EXPECT_EQ("1:hijklmn;", string(output.begin(), output.end())); 122 123 reader.SeekSet(30); 124 EXPECT_TRUE(reader.ReadData(10, output.data())); 125 EXPECT_EQ(40, reader.Tell()); 126 EXPECT_EQ("3:vwxyzABC", string(output.begin(), output.end())); 127 128 reader.SeekSet(0); 129 EXPECT_TRUE(reader.ReadData(10, output.data())); 130 EXPECT_EQ(10, reader.Tell()); 131 EXPECT_EQ("0:abcdefg;", string(output.begin(), output.end())); 132 } 133 134 // Test reading past the end of the buffer. 135 TEST(BufferReaderTest, ReadPastEndOfData) { 136 // This string is 26 characters long. 137 const string kInputData = "abcdefghijklmnopqrstuvwxyz"; 138 BufferReader reader(kInputData.data(), kInputData.size()); 139 140 // Must not be able to read past the end of the buffer. 141 std::vector<uint8_t> output(kInputData.size()); 142 reader.SeekSet(0); 143 EXPECT_FALSE(reader.ReadData(30, output.data())); 144 // The read pointer should not have moved. 145 EXPECT_EQ(0, reader.Tell()); 146 147 // Should still be able to read within the bounds of the buffer, despite the 148 // out-of-bounds read earlier. 149 EXPECT_TRUE(reader.ReadData(13, output.data())); 150 EXPECT_EQ(13, reader.Tell()); 151 152 // Now attempt another read past the end of the buffer, but starting from the 153 // ending position of the previous read operation. 154 EXPECT_FALSE(reader.ReadData(20, output.data() + reader.Tell())); 155 // The read pointer should be unchanged. 156 EXPECT_EQ(13, reader.Tell()); 157 158 // Read the rest of the data and make sure it matches the input. 159 EXPECT_TRUE(reader.ReadData(13, output.data() + reader.Tell())); 160 EXPECT_EQ(26, reader.Tell()); 161 162 EXPECT_EQ(kInputData, string(output.begin(), output.end())); 163 } 164 165 // Test string reads. 166 TEST(BufferReaderTest, ReadString) { 167 // Construct an input string. 168 string input("The quick brown fox jumps over the lazy dog."); 169 170 // Read the full string. 171 BufferReader full_reader(input.data(), input.size()); 172 string full_reader_output; 173 EXPECT_TRUE(full_reader.ReadString(input.size(), &full_reader_output)); 174 EXPECT_EQ(input.size(), full_reader.Tell()); 175 EXPECT_EQ(input, full_reader_output); 176 177 // Read the full string plus the null pointer. 178 BufferReader full_null_reader(input.data(), input.size() + 1); 179 string full_null_reader_output; 180 EXPECT_TRUE( 181 full_null_reader.ReadString(input.size() + 1, &full_null_reader_output)); 182 EXPECT_EQ(input.size() + 1, full_null_reader.Tell()); 183 EXPECT_EQ(input, full_null_reader_output); 184 185 // Read the first half of the string. 186 BufferReader half_reader(input.data(), input.size() / 2); 187 string half_reader_output; 188 EXPECT_TRUE(half_reader.ReadString(input.size() / 2, &half_reader_output)); 189 EXPECT_EQ(input.size() / 2, half_reader.Tell()); 190 EXPECT_EQ(input.substr(0, input.size() / 2), half_reader_output); 191 192 // Attempt to read past the end of the string. 193 BufferReader past_end_reader(input.data(), input.size()); 194 string past_end_reader_output; 195 EXPECT_FALSE( 196 past_end_reader.ReadString(input.size() + 2, &past_end_reader_output)); 197 198 // Create a vector with some extra padding behind it. The padding should be 199 // all zeroes. Read from this vector, with a size that encompasses the 200 // padding. 201 std::vector<char> input_vector(input.begin(), input.end()); 202 input_vector.resize(input.size() + 10, '\0'); 203 204 BufferReader vector_reader(input_vector.data(), input_vector.size()); 205 string vector_reader_output; 206 EXPECT_TRUE( 207 vector_reader.ReadString(input_vector.size(), &vector_reader_output)); 208 // The reader should have read past the padding too. 209 EXPECT_EQ(input_vector.size(), vector_reader.Tell()); 210 EXPECT_EQ(input, vector_reader_output); 211 } 212 213 string MakeStringWithNullsForSpaces(string str) { 214 std::replace(str.begin(), str.end(), ' ', '\0'); 215 return str; 216 } 217 218 TEST(BufferReaderTest, ReadDataString) { 219 // Construct an input string. 220 string input = MakeStringWithNullsForSpaces( 221 "The quick brown fox jumps over the lazy dog."); 222 223 BufferReader reader(input.data(), input.size()); 224 225 string expected_out; 226 string out; 227 out.resize(5); 228 EXPECT_TRUE(reader.ReadDataString(10, &out)); 229 expected_out = MakeStringWithNullsForSpaces("The quick "); 230 EXPECT_EQ(10, expected_out.size()) << "Sanity"; 231 EXPECT_EQ(expected_out, out); 232 233 out.resize(15); 234 EXPECT_TRUE(reader.ReadDataString(10, &out)); 235 expected_out = MakeStringWithNullsForSpaces("brown fox "); 236 EXPECT_EQ(10, expected_out.size()) << "Sanity"; 237 EXPECT_EQ(expected_out, out); 238 239 reader.SeekSet(reader.size()); 240 241 // Check destination contents don't get modified on failure. 242 out.resize(5); 243 expected_out = out; 244 EXPECT_FALSE(reader.ReadDataString(10, &out)); 245 EXPECT_EQ(expected_out, out) << "Should be unchanged."; 246 247 out.resize(15); 248 expected_out = out; 249 EXPECT_FALSE(reader.ReadDataString(10, &out)); 250 EXPECT_EQ(expected_out, out) << "Should be unchanged."; 251 252 EXPECT_FALSE(out.empty()) << "Sanity"; 253 EXPECT_TRUE(reader.ReadDataString(0, &out)); 254 EXPECT_TRUE(out.empty()) << "Read zero-length should clear output."; 255 } 256 257 // Reads data to a buffer and verifies that the buffer has not been modified 258 // beyond the writable boundaries. 259 TEST(BufferReaderTest, NoWritingOutOfBounds) { 260 // The input data contains all zeroes. 261 std::vector<uint8_t> input(800, 0); 262 BufferReader reader(input.data(), input.size()); 263 264 // A sentinel value that fills memory to detect when that section of memory is 265 // overwritten. If the memory shows another value, it means it has been 266 // overwritten. 267 const char kUnwrittenValue = 0xaa; 268 269 // Create a destination buffer filled with the above sentinel value. 270 std::vector<uint8_t> buffer(1000, kUnwrittenValue); 271 // Only write to the range [100, 900). 272 EXPECT_TRUE(reader.ReadData(800, buffer.data() + 100)); 273 274 // Check that the data was written to the writable part of the buffer. 275 EXPECT_EQ(input, 276 std::vector<uint8_t>(buffer.begin() + 100, buffer.begin() + 900)); 277 278 // Now make sure that the other parts of the buffer haven't been overwritten. 279 const std::vector<uint8_t> expected_unwritten_part(100, kUnwrittenValue); 280 EXPECT_EQ(expected_unwritten_part, 281 std::vector<uint8_t>(buffer.begin(), buffer.begin() + 100)); 282 EXPECT_EQ(expected_unwritten_part, 283 std::vector<uint8_t>(buffer.begin() + 900, buffer.begin() + 1000)); 284 } 285 286 } // namespace quipper 287