1#line 1 "main_test.function" 2SUITE_PRE_DEP 3#define TEST_SUITE_ACTIVE 4 5int verify_string( char **str ) 6{ 7 if( (*str)[0] != '"' || 8 (*str)[strlen( *str ) - 1] != '"' ) 9 { 10 mbedtls_fprintf( stderr, 11 "Expected string (with \"\") for parameter and got: %s\n", *str ); 12 return( -1 ); 13 } 14 15 (*str)++; 16 (*str)[strlen( *str ) - 1] = '\0'; 17 18 return( 0 ); 19} 20 21int verify_int( char *str, int *value ) 22{ 23 size_t i; 24 int minus = 0; 25 int digits = 1; 26 int hex = 0; 27 28 for( i = 0; i < strlen( str ); i++ ) 29 { 30 if( i == 0 && str[i] == '-' ) 31 { 32 minus = 1; 33 continue; 34 } 35 36 if( ( ( minus && i == 2 ) || ( !minus && i == 1 ) ) && 37 str[i - 1] == '0' && str[i] == 'x' ) 38 { 39 hex = 1; 40 continue; 41 } 42 43 if( ! ( ( str[i] >= '0' && str[i] <= '9' ) || 44 ( hex && ( ( str[i] >= 'a' && str[i] <= 'f' ) || 45 ( str[i] >= 'A' && str[i] <= 'F' ) ) ) ) ) 46 { 47 digits = 0; 48 break; 49 } 50 } 51 52 if( digits ) 53 { 54 if( hex ) 55 *value = strtol( str, NULL, 16 ); 56 else 57 *value = strtol( str, NULL, 10 ); 58 59 return( 0 ); 60 } 61 62MAPPING_CODE 63 64 mbedtls_fprintf( stderr, 65 "Expected integer for parameter and got: %s\n", str ); 66 return( KEY_VALUE_MAPPING_NOT_FOUND ); 67} 68 69 70/*----------------------------------------------------------------------------*/ 71/* Test Case code */ 72 73FUNCTION_CODE 74SUITE_POST_DEP 75 76#line !LINE_NO! "main_test.function" 77 78 79/*----------------------------------------------------------------------------*/ 80/* Test dispatch code */ 81 82int dep_check( char *str ) 83{ 84 if( str == NULL ) 85 return( 1 ); 86 87DEP_CHECK_CODE 88#line !LINE_NO! "main_test.function" 89 90 return( DEPENDENCY_NOT_SUPPORTED ); 91} 92 93int dispatch_test(int cnt, char *params[50]) 94{ 95 int ret; 96 ((void) cnt); 97 ((void) params); 98 99#if defined(TEST_SUITE_ACTIVE) 100 ret = DISPATCH_TEST_SUCCESS; 101 102 // Cast to void to avoid compiler warnings 103 (void)ret; 104 105DISPATCH_FUNCTION 106 { 107#line !LINE_NO! "main_test.function" 108 mbedtls_fprintf( stdout, 109 "FAILED\nSkipping unknown test function '%s'\n", 110 params[0] ); 111 fflush( stdout ); 112 ret = DISPATCH_TEST_FN_NOT_FOUND; 113 } 114#else 115 ret = DISPATCH_UNSUPPORTED_SUITE; 116#endif 117 return( ret ); 118} 119 120 121/*----------------------------------------------------------------------------*/ 122/* Main Test code */ 123 124#line !LINE_NO! "main_test.function" 125 126#define USAGE \ 127 "Usage: %s [OPTIONS] files...\n\n" \ 128 " Command line arguments:\n" \ 129 " files... One or more test data file. If no file is specified\n" \ 130 " the followimg default test case is used:\n" \ 131 " %s\n\n" \ 132 " Options:\n" \ 133 " -v | --verbose Display full information about each test\n" \ 134 " -h | --help Display this information\n\n", \ 135 argv[0], \ 136 "TESTCASE_FILENAME" 137 138 139int get_line( FILE *f, char *buf, size_t len ) 140{ 141 char *ret; 142 143 ret = fgets( buf, len, f ); 144 if( ret == NULL ) 145 return( -1 ); 146 147 if( strlen( buf ) && buf[strlen(buf) - 1] == '\n' ) 148 buf[strlen(buf) - 1] = '\0'; 149 if( strlen( buf ) && buf[strlen(buf) - 1] == '\r' ) 150 buf[strlen(buf) - 1] = '\0'; 151 152 return( 0 ); 153} 154 155int parse_arguments( char *buf, size_t len, char *params[50] ) 156{ 157 int cnt = 0, i; 158 char *cur = buf; 159 char *p = buf, *q; 160 161 params[cnt++] = cur; 162 163 while( *p != '\0' && p < buf + len ) 164 { 165 if( *p == '\\' ) 166 { 167 p++; 168 p++; 169 continue; 170 } 171 if( *p == ':' ) 172 { 173 if( p + 1 < buf + len ) 174 { 175 cur = p + 1; 176 params[cnt++] = cur; 177 } 178 *p = '\0'; 179 } 180 181 p++; 182 } 183 184 /* Replace newlines, question marks and colons in strings */ 185 for( i = 0; i < cnt; i++ ) 186 { 187 p = params[i]; 188 q = params[i]; 189 190 while( *p != '\0' ) 191 { 192 if( *p == '\\' && *(p + 1) == 'n' ) 193 { 194 p += 2; 195 *(q++) = '\n'; 196 } 197 else if( *p == '\\' && *(p + 1) == ':' ) 198 { 199 p += 2; 200 *(q++) = ':'; 201 } 202 else if( *p == '\\' && *(p + 1) == '?' ) 203 { 204 p += 2; 205 *(q++) = '?'; 206 } 207 else 208 *(q++) = *(p++); 209 } 210 *q = '\0'; 211 } 212 213 return( cnt ); 214} 215 216static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret ) 217{ 218 int ret; 219 char buf[10] = "xxxxxxxxx"; 220 const char ref[10] = "xxxxxxxxx"; 221 222 ret = mbedtls_snprintf( buf, n, "%s", "123" ); 223 if( ret < 0 || (size_t) ret >= n ) 224 ret = -1; 225 226 if( strncmp( ref_buf, buf, sizeof( buf ) ) != 0 || 227 ref_ret != ret || 228 memcmp( buf + n, ref + n, sizeof( buf ) - n ) != 0 ) 229 { 230 return( 1 ); 231 } 232 233 return( 0 ); 234} 235 236static int run_test_snprintf( void ) 237{ 238 return( test_snprintf( 0, "xxxxxxxxx", -1 ) != 0 || 239 test_snprintf( 1, "", -1 ) != 0 || 240 test_snprintf( 2, "1", -1 ) != 0 || 241 test_snprintf( 3, "12", -1 ) != 0 || 242 test_snprintf( 4, "123", 3 ) != 0 || 243 test_snprintf( 5, "123", 3 ) != 0 ); 244} 245 246int main(int argc, const char *argv[]) 247{ 248 /* Local Configurations and options */ 249 const char *default_filename = "TESTCASE_FILENAME"; 250 const char *test_filename = NULL; 251 const char **test_files = NULL; 252 int testfile_count = 0; 253 int option_verbose = 0; 254 255 /* Other Local variables */ 256 int arg_index = 1; 257 const char *next_arg; 258 int testfile_index, ret, i, cnt; 259 int total_errors = 0, total_tests = 0, total_skipped = 0; 260 FILE *file; 261 char buf[5000]; 262 char *params[50]; 263 void *pointer; 264 int stdout_fd = -1; 265 266#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ 267 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) 268 unsigned char alloc_buf[1000000]; 269 mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); 270#endif 271 272 /* 273 * The C standard doesn't guarantee that all-bits-0 is the representation 274 * of a NULL pointer. We do however use that in our code for initializing 275 * structures, which should work on every modern platform. Let's be sure. 276 */ 277 memset( &pointer, 0, sizeof( void * ) ); 278 if( pointer != NULL ) 279 { 280 mbedtls_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" ); 281 return( 1 ); 282 } 283 284 /* 285 * Make sure we have a snprintf that correctly zero-terminates 286 */ 287 if( run_test_snprintf() != 0 ) 288 { 289 mbedtls_fprintf( stderr, "the snprintf implementation is broken\n" ); 290 return( 0 ); 291 } 292 293 while( arg_index < argc) 294 { 295 next_arg = argv[ arg_index ]; 296 297 if( strcmp(next_arg, "--verbose" ) == 0 || 298 strcmp(next_arg, "-v" ) == 0 ) 299 { 300 option_verbose = 1; 301 } 302 else if( strcmp(next_arg, "--help" ) == 0 || 303 strcmp(next_arg, "-h" ) == 0 ) 304 { 305 mbedtls_fprintf( stdout, USAGE ); 306 mbedtls_exit( EXIT_SUCCESS ); 307 } 308 else 309 { 310 /* Not an option, therefore treat all further arguments as the file 311 * list. 312 */ 313 test_files = &argv[ arg_index ]; 314 testfile_count = argc - arg_index; 315 } 316 317 arg_index++; 318 } 319 320 /* If no files were specified, assume a default */ 321 if ( test_files == NULL || testfile_count == 0 ) 322 { 323 test_files = &default_filename; 324 testfile_count = 1; 325 } 326 327 /* Now begin to execute the tests in the testfiles */ 328 for ( testfile_index = 0; 329 testfile_index < testfile_count; 330 testfile_index++ ) 331 { 332 int unmet_dep_count = 0; 333 char *unmet_dependencies[20]; 334 335 test_filename = test_files[ testfile_index ]; 336 337 file = fopen( test_filename, "r" ); 338 if( file == NULL ) 339 { 340 mbedtls_fprintf( stderr, "Failed to open test file: %s\n", 341 test_filename ); 342 return( 1 ); 343 } 344 345 while( !feof( file ) ) 346 { 347 if( unmet_dep_count > 0 ) 348 { 349 mbedtls_fprintf( stderr, 350 "FATAL: Dep count larger than zero at start of loop\n" ); 351 mbedtls_exit( MBEDTLS_EXIT_FAILURE ); 352 } 353 unmet_dep_count = 0; 354 355 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 ) 356 break; 357 mbedtls_fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf ); 358 mbedtls_fprintf( stdout, " " ); 359 for( i = strlen( buf ) + 1; i < 67; i++ ) 360 mbedtls_fprintf( stdout, "." ); 361 mbedtls_fprintf( stdout, " " ); 362 fflush( stdout ); 363 364 total_tests++; 365 366 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 ) 367 break; 368 cnt = parse_arguments( buf, strlen(buf), params ); 369 370 if( strcmp( params[0], "depends_on" ) == 0 ) 371 { 372 for( i = 1; i < cnt; i++ ) 373 { 374 if( dep_check( params[i] ) != DEPENDENCY_SUPPORTED ) 375 { 376 if( 0 == option_verbose ) 377 { 378 /* Only one count is needed if not verbose */ 379 unmet_dep_count++; 380 break; 381 } 382 383 unmet_dependencies[ unmet_dep_count ] = strdup(params[i]); 384 if( unmet_dependencies[ unmet_dep_count ] == NULL ) 385 { 386 mbedtls_fprintf( stderr, "FATAL: Out of memory\n" ); 387 mbedtls_exit( MBEDTLS_EXIT_FAILURE ); 388 } 389 unmet_dep_count++; 390 } 391 } 392 393 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 ) 394 break; 395 cnt = parse_arguments( buf, strlen(buf), params ); 396 } 397 398 // If there are no unmet dependencies execute the test 399 if( unmet_dep_count == 0 ) 400 { 401 test_errors = 0; 402 403#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 404 /* Suppress all output from the library unless we're verbose 405 * mode 406 */ 407 if( !option_verbose ) 408 { 409 stdout_fd = redirect_output( &stdout, "/dev/null" ); 410 if( stdout_fd == -1 ) 411 { 412 /* Redirection has failed with no stdout so exit */ 413 exit( 1 ); 414 } 415 } 416#endif /* __unix__ || __APPLE__ __MACH__ */ 417 418 ret = dispatch_test( cnt, params ); 419 420#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 421 if( !option_verbose && restore_output( &stdout, stdout_fd ) ) 422 { 423 /* Redirection has failed with no stdout so exit */ 424 exit( 1 ); 425 } 426#endif /* __unix__ || __APPLE__ __MACH__ */ 427 428 } 429 430 if( unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE ) 431 { 432 total_skipped++; 433 mbedtls_fprintf( stdout, "----\n" ); 434 435 if( 1 == option_verbose && ret == DISPATCH_UNSUPPORTED_SUITE ) 436 { 437 mbedtls_fprintf( stdout, " Test Suite not enabled" ); 438 } 439 440 if( 1 == option_verbose && unmet_dep_count > 0 ) 441 { 442 mbedtls_fprintf( stdout, " Unmet dependencies: " ); 443 for( i = 0; i < unmet_dep_count; i++ ) 444 { 445 mbedtls_fprintf(stdout, "%s ", 446 unmet_dependencies[i]); 447 free(unmet_dependencies[i]); 448 } 449 mbedtls_fprintf( stdout, "\n" ); 450 } 451 fflush( stdout ); 452 453 unmet_dep_count = 0; 454 } 455 else if( ret == DISPATCH_TEST_SUCCESS && test_errors == 0 ) 456 { 457 mbedtls_fprintf( stdout, "PASS\n" ); 458 fflush( stdout ); 459 } 460 else if( ret == DISPATCH_INVALID_TEST_DATA ) 461 { 462 mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" ); 463 fclose(file); 464 mbedtls_exit( 2 ); 465 } 466 else 467 total_errors++; 468 469 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 ) 470 break; 471 if( strlen(buf) != 0 ) 472 { 473 mbedtls_fprintf( stderr, "Should be empty %d\n", 474 (int) strlen(buf) ); 475 return( 1 ); 476 } 477 } 478 fclose(file); 479 480 /* In case we encounter early end of file */ 481 for( i = 0; i < unmet_dep_count; i++ ) 482 free( unmet_dependencies[i] ); 483 } 484 485 mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n"); 486 if( total_errors == 0 ) 487 mbedtls_fprintf( stdout, "PASSED" ); 488 else 489 mbedtls_fprintf( stdout, "FAILED" ); 490 491 mbedtls_fprintf( stdout, " (%d / %d tests (%d skipped))\n", 492 total_tests - total_errors, total_tests, total_skipped ); 493 494#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ 495 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) 496#if defined(MBEDTLS_MEMORY_DEBUG) 497 mbedtls_memory_buffer_alloc_status(); 498#endif 499 mbedtls_memory_buffer_alloc_free(); 500#endif 501 502#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 503 if( stdout_fd != -1 ) 504 close_output( stdout ); 505#endif /* __unix__ || __APPLE__ __MACH__ */ 506 507 return( total_errors != 0 ); 508} 509 510