1/* Copyright (c) 2011 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 * Tests for statful_util functions.
6 */
7
8#include <stdint.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define _STUB_IMPLEMENTATION_  /* So we can use memset() ourselves */
14
15#include "stateful_util.h"
16#include "test_common.h"
17#include "utility.h"
18#include "vboot_common.h"
19
20
21/* Test StatefulInit */
22static void StatefulInitTest(void) {
23  MemcpyState s;
24  char buf[128];
25
26  memset(&s, 0, sizeof(s));
27  s.overrun = 1;
28  StatefulInit(&s, buf, 128);
29  TEST_EQ(0, s.overrun, "StatefulInit() overrun");
30  TEST_EQ(128, s.remaining_len, "StatefulInit() len");
31  TEST_PTR_EQ(buf, s.remaining_buf, "StatefulInit() buf");
32}
33
34
35/* Test StatefulSkip */
36static void StatefulSkipTest(void) {
37  MemcpyState s;
38  char buf[128];
39
40  /* Small skip */
41  StatefulInit(&s, buf, 128);
42  TEST_PTR_EQ(&s, StatefulSkip(&s, 5), "StatefulSkip(5) retval");
43  TEST_EQ(128 - 5, s.remaining_len, "StatefulSkip(5) len");
44  TEST_PTR_EQ(buf + 5, s.remaining_buf, "StatefulSkip(5) buf");
45  TEST_EQ(0, s.overrun, "StatefulSkip(5) overrun");
46
47  /* Use entire buffer */
48  StatefulInit(&s, buf, 128);
49  TEST_PTR_EQ(&s, StatefulSkip(&s, 128), "StatefulSkip(all) retval");
50  TEST_EQ(0, s.remaining_len, "StatefulSkip(all) len");
51  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulSkip(all) buf");
52  TEST_EQ(0, s.overrun, "StatefulSkip(all) overrun");
53
54  /* Zero-length skip is ok (but meaningless) */
55  TEST_PTR_EQ(&s, StatefulSkip(&s, 0), "StatefulSkip(0) retval");
56  TEST_EQ(0, s.remaining_len, "StatefulSkip(0) len");
57  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulSkip(0) buf");
58  TEST_EQ(0, s.overrun, "StatefulSkip(0) overrun");
59
60  /* Can't use even one byte past that */
61  TEST_PTR_EQ(NULL, StatefulSkip(&s, 1), "StatefulSkip(+1) retval");
62  TEST_EQ(0, s.remaining_len, "StatefulSkip(+1) len");
63  TEST_EQ(1, s.overrun, "StatefulSkip(+1) overrun");
64
65  /* Overrun */
66  StatefulInit(&s, buf, 128);
67  TEST_PTR_EQ(NULL, StatefulSkip(&s, 256), "StatefulSkip(256) retval");
68  TEST_EQ(1, s.overrun, "StatefulSkip(256) overrun");
69  /* Once overrun, always overrun, even if we now ask for a small skip */
70  TEST_PTR_EQ(NULL, StatefulSkip(&s, 1), "StatefulSkip(256+1) retval");
71  TEST_EQ(1, s.overrun, "StatefulSkip(256+1) overrun");
72
73  /* Overrun with potential wraparound */
74  StatefulInit(&s, buf, 128);
75  TEST_PTR_EQ(NULL, StatefulSkip(&s, -1), "StatefulSkip(-1) retval");
76  TEST_EQ(1, s.overrun, "StatefulSkip(-1) overrun");
77}
78
79
80/* Test StatefulMemset_r */
81static void StatefulMemset_rTest(void) {
82  MemcpyState s;
83  char buf[129];
84  char want[129];
85
86  memset(want, 0, sizeof(want));
87  memset(buf, 0, sizeof(buf));
88
89  /* Small sets */
90  StatefulInit(&s, buf, 128);
91  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'A', 5), "StatefulMemset_r(5) retval");
92  TEST_EQ(128 - 5, s.remaining_len, "StatefulMemset_r(5) len");
93  TEST_PTR_EQ(buf + 5, s.remaining_buf, "StatefulMemset_r(5) buf");
94  /* Using strcmp() is a convenient way to check that we didn't
95   * overwrite the 0-byte following what we expected to set. */
96  TEST_EQ(0, strcmp("AAAAA", buf), "StatefulMemset_r(5) contents");
97  TEST_EQ(0, s.overrun, "StatefulMemset_r(5) overrun");
98  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'B', 3), "StatefulMemset_r(3) retval");
99  TEST_EQ(0, strcmp("AAAAABBB", buf), "StatefulMemset_r(3) contents");
100
101  /* Use entire buffer */
102  StatefulInit(&s, buf, 128);
103  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'C', 128),
104              "StatefulMemset_r(all) retval");
105  TEST_EQ(0, s.remaining_len, "StatefulMemset_r(all) len");
106  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulMemset_r(all) buf");
107  TEST_EQ(0, s.overrun, "StatefulMemset_r(all) overrun");
108  memset(want, 'C', 128);
109  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(all) contents");
110
111  /* Zero-length set is ok (but meaningless) */
112  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'D', 0), "StatefulMemset_r(0) retval");
113  TEST_EQ(0, s.remaining_len, "StatefulMemset_r(0) len");
114  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulMemset_r(0) buf");
115  TEST_EQ(0, s.overrun, "StatefulMemset_r(0) overrun");
116  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(0) contents");
117
118  /* Can't use even one byte past that */
119  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'E', 1),
120              "StatefulMemset_r(+1) retval");
121  TEST_EQ(0, s.remaining_len, "StatefulMemset_r(+1) len");
122  TEST_EQ(1, s.overrun, "StatefulMemset_r(+1) overrun");
123  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
124
125  /* Overrun */
126  StatefulInit(&s, buf, 128);
127  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'F', 256),
128              "StatefulMemset_r(256) retval");
129  TEST_EQ(1, s.overrun, "StatefulMemset_r(256) overrun");
130  /* Once overrun, always overrun, even if we now ask for a small skip */
131  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'G', 1),
132              "StatefulMemset_r(256+1) retval");
133  TEST_EQ(1, s.overrun, "StatefulMemset_r(256+1) overrun");
134  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
135
136  /* Overrun with potential wraparound */
137  StatefulInit(&s, buf, 128);
138  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'H', -1),
139              "StatefulMemset_r(-1) retval");
140  TEST_EQ(1, s.overrun, "StatefulMemset_r(-1) overrun");
141  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
142}
143
144
145/* Test StatefulMemcpy_r */
146static void StatefulMemcpy_rTest(void) {
147  MemcpyState s;
148  char buf[129];
149  char want[129];
150  char* src1 = "Doogie";
151  char* src2 = "Howserrr";
152  char* src3 = "WholeBuffr";
153
154  memset(want, 0, sizeof(want));
155  memset(buf, 0, sizeof(buf));
156
157  /* Small copies */
158  StatefulInit(&s, buf, 128);
159  TEST_PTR_EQ(src1, StatefulMemcpy_r(&s, src1, 6),
160              "StatefulMemcpy_r(6) retval");
161  TEST_EQ(128 - 6, s.remaining_len, "StatefulMemcpy_r(6) len");
162  TEST_PTR_EQ(buf + 6, s.remaining_buf, "StatefulMemcpy_r(6) buf");
163  /* Using strcmp() is a convenient way to check that we didn't
164   * overwrite the 0-byte following what we expected to copy. */
165  TEST_EQ(0, strcmp("Doogie", buf), "StatefulMemcpy_r(6) contents");
166  TEST_EQ(0, s.overrun, "StatefulMemcpy_r(6) overrun");
167  TEST_PTR_EQ(src2, StatefulMemcpy_r(&s, src2, 8),
168              "StatefulMemcpy_r(8) retval");
169  TEST_EQ(0, strcmp("DoogieHowserrr", buf), "StatefulMemcpy_r(8) contents");
170
171  /* Use entire buffer */
172  memset(buf, 42, sizeof(buf));
173  StatefulInit(&s, buf, 10);
174  TEST_PTR_EQ(src3, StatefulMemcpy_r(&s, src3, 10),
175              "StatefulMemcpy_r(all) retval");
176  TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(all) len");
177  TEST_PTR_EQ(buf + 10, s.remaining_buf, "StatefulMemcpy_r(all) buf");
178  TEST_EQ(0, s.overrun, "StatefulMemcpy_r(all) overrun");
179  TEST_EQ(0, memcmp(src3, buf, 10), "StatefulMemcpy_r(all) contents");
180  TEST_EQ(42, buf[10], "StatefulMemcpy_r(all) contents+1");
181
182  /* Zero-length copy is ok (but meaningless) */
183  TEST_PTR_EQ(src1, StatefulMemcpy_r(&s, src1, 0),
184              "StatefulMemcpy_r(0) retval");
185  TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(0) len");
186  TEST_PTR_EQ(buf + 10, s.remaining_buf, "StatefulMemcpy_r(0) buf");
187  TEST_EQ(0, s.overrun, "StatefulMemcpy_r(0) overrun");
188  TEST_EQ(42, buf[10], "StatefulMemcpy_r(0) contents+1");
189
190  /* Can't use even one byte past that */
191  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, src1, 1),
192              "StatefulMemcpy_r(+1) retval");
193  TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(+1) len");
194  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(+1) overrun");
195  TEST_EQ(42, buf[10], "StatefulMemcpy_r(+1) contents");
196
197  /* Overrun */
198  memset(buf, 0, sizeof(buf));
199  StatefulInit(&s, buf, 8);
200  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "MoreThan8", 9),
201              "StatefulMemcpy_r(9) retval");
202  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(9) overrun");
203  /* Once overrun, always overrun, even if we now ask for a small skip */
204  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "Less", 4),
205              "StatefulMemcpy_r(9+1) retval");
206  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(9+1) overrun");
207  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy_r(+1) contents");
208
209  /* Overrun with potential wraparound */
210  StatefulInit(&s, buf, 128);
211  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "FOO", -1),
212              "StatefulMemcpy_r(-1) retval");
213  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(-1) overrun");
214  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy_r(+1) contents");
215}
216
217
218/* Test StatefulMemcpy */
219static void StatefulMemcpyTest(void) {
220  MemcpyState s;
221  char buf[129];
222  char want[129];
223  char* src1 = "ThisIsATest";
224  char* src2 = "ThisIsOnlyATest";
225
226  memset(want, 0, sizeof(want));
227  memset(buf, 0, sizeof(buf));
228
229  /* Small copies */
230  StatefulInit(&s, src1, 12);
231  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 6), "StatefulMemcpy(6) retval");
232  TEST_EQ(6, s.remaining_len, "StatefulMemcpy(6) len");
233  TEST_PTR_EQ(src1 + 6, s.remaining_buf, "StatefulMemcpy(6) buf");
234  /* Using strcmp() is a convenient way to check that we didn't
235   * overwrite the 0-byte following what we expected to copy. */
236  TEST_EQ(0, strcmp("ThisIs", buf), "StatefulMemcpy(6) contents");
237  TEST_EQ(0, s.overrun, "StatefulMemcpy(6) overrun");
238  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 5), "StatefulMemcpy(5) retval");
239  /* Note that we shouldn't have copied the last byte out of the
240   * stateful buffer, so we don't overwrite the last character of the
241   * string that was in buf. */
242  TEST_EQ(0, strcmp("ATests", buf), "StatefulMemcpy(5) contents");
243
244  /* Use entire buffer */
245  memset(buf, 1, sizeof(buf));
246  StatefulInit(&s, src2, 16);
247  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 16), "StatefulMemcpy(all) retval");
248  TEST_EQ(0, s.remaining_len, "StatefulMemcpy(all) len");
249  TEST_PTR_EQ(src2 + 16, s.remaining_buf, "StatefulMemcpy(all) buf");
250  TEST_EQ(0, s.overrun, "StatefulMemcpy(all) overrun");
251  TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(all) contents");
252
253  /* Zero-length copy is ok (but meaningless) */
254  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 0),
255              "StatefulMemcpy(0) retval");
256  TEST_EQ(0, s.remaining_len, "StatefulMemcpy(0) len");
257  TEST_PTR_EQ(src2 + 16, s.remaining_buf, "StatefulMemcpy(0) buf");
258  TEST_EQ(0, s.overrun, "StatefulMemcpy(0) overrun");
259  TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(0) contents");
260
261  /* Can't use even one byte past that */
262  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 1),
263              "StatefulMemcpy(+1) retval");
264  TEST_EQ(0, s.remaining_len, "StatefulMemcpy(+1) len");
265  TEST_EQ(1, s.overrun, "StatefulMemcpy(+1) overrun");
266  TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(+1) contents");
267
268  /* Overrun */
269  memset(buf, 0, sizeof(buf));
270  StatefulInit(&s, "Small", 5);
271  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 9), "StatefulMemcpy(9) retval");
272  TEST_EQ(1, s.overrun, "StatefulMemcpy(9) overrun");
273  /* Once overrun, always overrun, even if we now ask for a small skip */
274  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 4),
275              "StatefulMemcpy(9+1) retval");
276  TEST_EQ(1, s.overrun, "StatefulMemcpy(9+1) overrun");
277  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy(+1) contents");
278
279  /* Overrun with potential wraparound */
280  StatefulInit(&s, "Larger", 6);
281  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, -1), "StatefulMemcpy(-1) retval");
282  TEST_EQ(1, s.overrun, "StatefulMemcpy(-1) overrun");
283  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy(+1) contents");
284}
285
286
287int main(int argc, char* argv[]) {
288  int error_code = 0;
289
290  StatefulInitTest();
291  StatefulSkipTest();
292  StatefulMemset_rTest();
293  StatefulMemcpy_rTest();
294  StatefulMemcpyTest();
295
296  if (!gTestSuccess)
297    error_code = 255;
298
299  return error_code;
300}
301