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 <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