1 : /*
2 : * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * Unit tests for struct NCInstBytes in ncinstbuffer.{h,cc}.
9 : */
10 :
11 : #ifndef NACL_TRUSTED_BUT_NOT_TCB
12 : #error("This file is not meant for use in the TCB")
13 : #endif
14 :
15 : #include <stdio.h>
16 :
17 : #include "gtest/gtest.h"
18 :
19 : #include "native_client/src/trusted/validator/x86/ncinstbuffer.h"
20 :
21 : namespace {
22 :
23 : /* Constant defining maximum buffer size for memory. */
24 : const size_t kMaxBufferSize = 30;
25 :
26 : /* Test harness for class NCRemainingMemory. */
27 : class NCInstBytesTests : public ::testing::Test {
28 : protected:
29 : void SetUp();
30 : NCInstBytesTests();
31 :
32 : /* Data for testing. */
33 : NCInstBytes _bytes; /* Inst bytes (read). */
34 : NCRemainingMemory _memory; /* Memory being tested. */
35 : uint8_t _buffer[kMaxBufferSize]; /* Memory buffer to use. */
36 : const size_t _buffer_size; /* Actually size of test data. */
37 : static const char* kTestData; /* Data put into memory for testing. */
38 :
39 : /* Verify if the contents of kTestData matches the contents
40 : * of _bytes, up to _buffer_size; Remaining elements are zero.
41 : */
42 : void VerifyBytesMatchTestData();
43 : };
44 :
45 : const char* NCInstBytesTests::kTestData = "Test data";
46 :
47 : NCInstBytesTests::NCInstBytesTests()
48 1 : : _buffer_size(strlen(kTestData)) {
49 : /* Fill memory buffer with bad test data, so that we know if bad accesses
50 : * occur past the end of the buffer.
51 : */
52 1 : for (size_t i = 0; i < kMaxBufferSize; ++i) {
53 1 : _buffer[i] = 'X';
54 1 : }
55 : /* Now fill in the good test data. */
56 1 : for (size_t i = 0; i < _buffer_size; ++i) {
57 1 : _buffer[i] = (uint8_t) kTestData[i];
58 : }
59 1 : }
60 :
61 1 : void NCInstBytesTests::VerifyBytesMatchTestData() {
62 : /* First show that while there is real data in the memory,
63 : * it has been copied to the bytes buffer.
64 : */
65 : size_t match_limit =
66 1 : (_bytes.length <= _buffer_size) ? _bytes.length : _buffer_size;
67 1 : for (size_t i = 0; i < match_limit; ++i) {
68 1 : EXPECT_EQ(_bytes.byte[i], kTestData[i])
69 : << "value verification of byte " << i;
70 1 : }
71 : /* Now show that any remaining bytes (after the memory
72 : * has been read) are 0.
73 : */
74 1 : for (size_t i = match_limit; i < _bytes.length; ++i) {
75 1 : EXPECT_EQ(0, _bytes.byte[i])
76 : << "zero verification of byte " << i;
77 1 : }
78 1 : }
79 :
80 1 : void NCInstBytesTests::SetUp() {
81 1 : NCRemainingMemoryInit(_buffer, _buffer_size, &_memory);
82 1 : NCInstBytesInitMemory(&_bytes, &_memory);
83 : /* Be sure to verify that we can run the tests, which require
84 : * a couple of extra slots for overflow.
85 : */
86 1 : ASSERT_LT(_buffer_size + 1, (size_t) MAX_INST_LENGTH)
87 1 : << "Set up failed due to kTestData being too long.";
88 1 : }
89 :
90 : /* Test function NCInstBytesPeek, and see if it properly sees the data in
91 : * the instruction buffer.
92 : */
93 3 : TEST_F(NCInstBytesTests, PeekGetsData) {
94 : /* First verify that we get text as defined in the test data. */
95 1 : for (size_t i = 0; i < _buffer_size; ++i) {
96 1 : EXPECT_EQ(NCInstBytesPeek(&_bytes, i), (uint8_t) kTestData[i])
97 : << "peeking " << i << " bytes ahead.";
98 1 : }
99 : /* Now verify that if we look past the end of the data, we
100 : * get 0.
101 : */
102 1 : EXPECT_EQ(0, NCInstBytesPeek(&_bytes, _buffer_size))
103 : << "peeking one byte past end of buffer.";
104 1 : EXPECT_EQ(0, NCInstBytesPeek(&_bytes, _buffer_size + 100))
105 : << "peeking 100 bytes past end of buffer.";
106 1 : EXPECT_EQ(0, _bytes.length);
107 1 : VerifyBytesMatchTestData();
108 1 : }
109 :
110 : /* Test function NCInstBytesRead, and see if it properly read
111 : * data from the memory buffer.
112 : */
113 3 : TEST_F(NCInstBytesTests, ReadGetsData) {
114 : /* First verify that we get text as defined in the test data. */
115 1 : for (size_t i = 0; i < _buffer_size; ++i) {
116 1 : EXPECT_EQ(NCInstBytesRead(&_bytes), (uint8_t) kTestData[i])
117 : << "after reading " << i << " characters";
118 1 : VerifyBytesMatchTestData();
119 1 : }
120 1 : EXPECT_EQ(_buffer_size, _bytes.length);
121 1 : VerifyBytesMatchTestData();
122 : /* Now verify that zero is returned for any additional reads. */
123 1 : for (size_t i = _bytes.length; i < MAX_INST_LENGTH; ++i) {
124 1 : EXPECT_EQ(0, NCInstBytesRead(&_bytes))
125 : << "after reading all characters";
126 1 : }
127 1 : VerifyBytesMatchTestData();
128 : /* Verify that we can apply a read, even if buffer overflow occurs,
129 : * and the only effect is that the buffer length is not increased.
130 : */
131 1 : EXPECT_EQ(MAX_INST_LENGTH, _bytes.length);
132 1 : EXPECT_EQ(0, NCInstBytesRead(&_bytes));
133 1 : EXPECT_EQ(MAX_INST_LENGTH, _bytes.length);
134 1 : }
135 :
136 : /* Test function NCInstBytesReadBytes, and see if it properly reads
137 : * data from the memory buffer.
138 : */
139 3 : TEST_F(NCInstBytesTests, ReadBytesGetsData) {
140 : /* First verify that we get text as defined in the test data. */
141 1 : size_t chars_read = 0;
142 1 : size_t stride = 4;
143 1 : VerifyBytesMatchTestData();
144 1 : while (chars_read < MAX_INST_LENGTH) {
145 1 : if ((chars_read + stride) > MAX_INST_LENGTH) {
146 1 : stride = MAX_INST_LENGTH - chars_read;
147 : }
148 1 : NCInstBytesReadBytes(stride, &_bytes);
149 1 : chars_read += stride;
150 1 : VerifyBytesMatchTestData();
151 1 : }
152 : /* Verify that we can apply additional reads without overflowing
153 : * the buffer.
154 : */
155 1 : NCInstBytesReadBytes(2, &_bytes);
156 1 : EXPECT_EQ(MAX_INST_LENGTH, _bytes.length) << "Buffer overflow fix failed.";
157 1 : }
158 :
159 : /* Test function NCInstBytesReset, and see if we back up to
160 : * the beginning of the instruction.
161 : */
162 3 : TEST_F(NCInstBytesTests, Reset) {
163 : /* First read some bytes into the bytes buffer. */
164 1 : NCInstBytesReadBytes(5, &_bytes);
165 1 : VerifyBytesMatchTestData();
166 : /* Now reset and see if we moved back. */
167 1 : NCInstBytesReset(&_bytes);
168 1 : EXPECT_EQ(0, _bytes.length) << "Reset didn't fix buffer length.";
169 1 : VerifyBytesMatchTestData();
170 1 : EXPECT_EQ(0, _memory.read_length) << "Reset didn't fix memory length.";
171 1 : EXPECT_EQ(0, _memory.overflow_count) << "Reset didn't fix memory overflow.";
172 1 : EXPECT_EQ((void*) _buffer, (void*) _memory.cur_pos)
173 : << "Reset did not reset memory.";
174 1 : }
175 :
176 : }; // anonymous namespace
177 :
178 1 : int main(int argc, char *argv[]) {
179 1 : testing::InitGoogleTest(&argc, argv);
180 1 : return RUN_ALL_TESTS();
181 1 : }
|