1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/msf/msf_byte_stream.h"
16 :
17 : #include <algorithm>
18 :
19 : #include "gtest/gtest.h"
20 :
21 : namespace msf {
22 :
23 : namespace {
24 :
25 : class TestMsfStream : public MsfStream {
26 : public:
27 E : explicit TestMsfStream(size_t length) : MsfStream(length) {}
28 :
29 E : virtual ~TestMsfStream() {}
30 :
31 E : bool ReadBytesAt(size_t pos, size_t count, void* dest) override {
32 E : DCHECK(dest != NULL);
33 :
34 E : if (count > length() - pos)
35 i : return false;
36 :
37 E : ::memset(dest, 0xFF, count);
38 :
39 E : return true;
40 E : }
41 : };
42 :
43 : } // namespace
44 :
45 E : TEST(MsfByteStreamTest, InitFromByteArray) {
46 E : uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};
47 :
48 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
49 E : EXPECT_TRUE(stream->Init(data, arraysize(data)));
50 E : EXPECT_EQ(arraysize(data), stream->length());
51 E : EXPECT_TRUE(stream->data() != NULL);
52 :
53 E : for (size_t i = 0; i < stream->length(); ++i) {
54 E : uint8_t num = 0;
55 E : EXPECT_TRUE(stream->ReadBytesAt(i, 1, &num));
56 E : EXPECT_EQ(data[i], num);
57 E : }
58 E : }
59 :
60 E : TEST(MsfByteStreamTest, InitFromMsfStream) {
61 E : scoped_refptr<TestMsfStream> test_stream(new TestMsfStream(64));
62 :
63 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
64 E : EXPECT_TRUE(stream->Init(test_stream.get()));
65 E : EXPECT_EQ(test_stream->length(), stream->length());
66 E : EXPECT_TRUE(stream->data() != NULL);
67 :
68 E : for (size_t i = 0; i < stream->length(); ++i) {
69 E : uint8_t num = 0;
70 E : EXPECT_TRUE(stream->ReadBytesAt(i, 1, &num));
71 E : EXPECT_EQ(0xFF, num);
72 E : }
73 E : }
74 :
75 E : TEST(MsfByteStreamTest, InitFromMsfStreamPart) {
76 E : uint8_t data[] = {0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
77 E : scoped_refptr<MsfByteStream> test_stream(new MsfByteStream());
78 E : EXPECT_TRUE(test_stream->Init(data, arraysize(data)));
79 :
80 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
81 E : EXPECT_TRUE(stream->Init(test_stream.get(), 2, 7));
82 E : EXPECT_EQ(7, stream->length());
83 E : EXPECT_TRUE(stream->data() != NULL);
84 :
85 E : for (size_t i = 0; i < stream->length(); ++i) {
86 E : uint8_t num = 0;
87 E : EXPECT_TRUE(stream->ReadBytesAt(i, 1, &num));
88 E : EXPECT_EQ(data[i + 2], num);
89 E : }
90 E : }
91 :
92 E : TEST(MsfByteStreamTest, ReadBytesAt) {
93 E : uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
94 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
95 E : EXPECT_TRUE(stream->Init(data, arraysize(data)));
96 :
97 : // Try a few in-bounds reads.
98 E : for (size_t pos = 0; pos < sizeof(data); ++pos) {
99 E : uint8_t buffer[4] = {};
100 E : size_t to_read = std::min(sizeof(buffer), stream->length() - pos);
101 E : EXPECT_TRUE(stream->ReadBytesAt(pos, to_read, buffer));
102 :
103 E : EXPECT_EQ(0U, ::memcmp(buffer, data + pos, to_read));
104 E : }
105 :
106 : // Try some out of bounds reads.
107 E : for (size_t len = 1; len <= sizeof(data); ++len) {
108 E : uint8_t buf[sizeof(data) + 1] = {};
109 :
110 E : EXPECT_FALSE(stream->ReadBytesAt(sizeof(data) - len + 1, len, buf));
111 E : for (auto c : buf)
112 E : EXPECT_EQ(0U, c);
113 E : }
114 E : }
115 :
116 E : TEST(MsfByteStreamTest, GetWritableStream) {
117 E : scoped_refptr<MsfStream> stream(new MsfByteStream());
118 E : scoped_refptr<WritableMsfStream> writer1 = stream->GetWritableStream();
119 E : EXPECT_TRUE(writer1.get() != NULL);
120 :
121 : // NOTE: This is a condition that only needs to be true currently because
122 : // of limitations in the WritableMsfByteStream implementation. When we
123 : // move to a proper interface implementation with shared storage state,
124 : // this limitation will be removed.
125 E : scoped_refptr<WritableMsfStream> writer2 = stream->GetWritableStream();
126 E : EXPECT_EQ(writer1.get(), writer2.get());
127 E : }
128 :
129 E : TEST(WritableMsfByteStreamTest, WriterChangesReaderLengthButNotCursor) {
130 E : scoped_refptr<MsfStream> reader(new MsfByteStream());
131 E : scoped_refptr<WritableMsfStream> writer = reader->GetWritableStream();
132 E : ASSERT_TRUE(writer.get() != NULL);
133 :
134 E : EXPECT_EQ(reader->length(), 0u);
135 E : EXPECT_EQ(writer->length(), 0u);
136 E : EXPECT_EQ(writer->pos(), 0u);
137 E : writer->Consume(10);
138 E : EXPECT_EQ(reader->length(), 10u);
139 E : EXPECT_EQ(writer->length(), 10u);
140 E : EXPECT_EQ(writer->pos(), 10u);
141 E : }
142 :
143 : } // namespace msf
|