Home | History | Annotate | Download | only in quipper
      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