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 */
StatefulInitTest(void)22 static 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 */
StatefulSkipTest(void)36 static 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 */
StatefulMemset_rTest(void)81 static 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 */
StatefulMemcpy_rTest(void)146 static 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 */
StatefulMemcpyTest(void)219 static 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 
main(int argc,char * argv[])287 int 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