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