host_test.function 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. #line 2 "suites/host_test.function"
  2. /**
  3. * \brief Verifies that string is in string parameter format i.e. "<str>"
  4. * It also strips enclosing '"' from the input string.
  5. *
  6. * \param str String parameter.
  7. *
  8. * \return 0 if success else 1
  9. */
  10. int verify_string( char **str )
  11. {
  12. if( ( *str )[0] != '"' ||
  13. ( *str )[strlen( *str ) - 1] != '"' )
  14. {
  15. mbedtls_fprintf( stderr,
  16. "Expected string (with \"\") for parameter and got: %s\n", *str );
  17. return( -1 );
  18. }
  19. ( *str )++;
  20. ( *str )[strlen( *str ) - 1] = '\0';
  21. return( 0 );
  22. }
  23. /**
  24. * \brief Verifies that string is an integer. Also gives the converted
  25. * integer value.
  26. *
  27. * \param str Input string.
  28. * \param value Pointer to int for output value.
  29. *
  30. * \return 0 if success else 1
  31. */
  32. int verify_int( char *str, int *value )
  33. {
  34. size_t i;
  35. int minus = 0;
  36. int digits = 1;
  37. int hex = 0;
  38. for( i = 0; i < strlen( str ); i++ )
  39. {
  40. if( i == 0 && str[i] == '-' )
  41. {
  42. minus = 1;
  43. continue;
  44. }
  45. if( ( ( minus && i == 2 ) || ( !minus && i == 1 ) ) &&
  46. str[i - 1] == '0' && ( str[i] == 'x' || str[i] == 'X' ) )
  47. {
  48. hex = 1;
  49. continue;
  50. }
  51. if( ! ( ( str[i] >= '0' && str[i] <= '9' ) ||
  52. ( hex && ( ( str[i] >= 'a' && str[i] <= 'f' ) ||
  53. ( str[i] >= 'A' && str[i] <= 'F' ) ) ) ) )
  54. {
  55. digits = 0;
  56. break;
  57. }
  58. }
  59. if( digits )
  60. {
  61. if( hex )
  62. *value = strtol( str, NULL, 16 );
  63. else
  64. *value = strtol( str, NULL, 10 );
  65. return( 0 );
  66. }
  67. mbedtls_fprintf( stderr,
  68. "Expected integer for parameter and got: %s\n", str );
  69. return( KEY_VALUE_MAPPING_NOT_FOUND );
  70. }
  71. /**
  72. * \brief Usage string.
  73. *
  74. */
  75. #define USAGE \
  76. "Usage: %s [OPTIONS] files...\n\n" \
  77. " Command line arguments:\n" \
  78. " files... One or more test data files. If no file is\n" \
  79. " specified the following default test case\n" \
  80. " file is used:\n" \
  81. " %s\n\n" \
  82. " Options:\n" \
  83. " -v | --verbose Display full information about each test\n" \
  84. " -h | --help Display this information\n\n", \
  85. argv[0], \
  86. "TESTCASE_FILENAME"
  87. /**
  88. * \brief Read a line from the passed file pointer.
  89. *
  90. * \param f FILE pointer
  91. * \param buf Pointer to memory to hold read line.
  92. * \param len Length of the buf.
  93. *
  94. * \return 0 if success else -1
  95. */
  96. int get_line( FILE *f, char *buf, size_t len )
  97. {
  98. char *ret;
  99. int i = 0, str_len = 0, has_string = 0;
  100. /* Read until we get a valid line */
  101. do
  102. {
  103. ret = fgets( buf, len, f );
  104. if( ret == NULL )
  105. return( -1 );
  106. str_len = strlen( buf );
  107. /* Skip empty line and comment */
  108. if ( str_len == 0 || buf[0] == '#' )
  109. continue;
  110. has_string = 0;
  111. for ( i = 0; i < str_len; i++ )
  112. {
  113. char c = buf[i];
  114. if ( c != ' ' && c != '\t' && c != '\n' &&
  115. c != '\v' && c != '\f' && c != '\r' )
  116. {
  117. has_string = 1;
  118. break;
  119. }
  120. }
  121. } while( !has_string );
  122. /* Strip new line and carriage return */
  123. ret = buf + strlen( buf );
  124. if( ret-- > buf && *ret == '\n' )
  125. *ret = '\0';
  126. if( ret-- > buf && *ret == '\r' )
  127. *ret = '\0';
  128. return( 0 );
  129. }
  130. /**
  131. * \brief Splits string delimited by ':'. Ignores '\:'.
  132. *
  133. * \param buf Input string
  134. * \param len Input string length
  135. * \param params Out params found
  136. * \param params_len Out params array len
  137. *
  138. * \return Count of strings found.
  139. */
  140. static int parse_arguments( char *buf, size_t len, char **params,
  141. size_t params_len )
  142. {
  143. size_t cnt = 0, i;
  144. char *cur = buf;
  145. char *p = buf, *q;
  146. params[cnt++] = cur;
  147. while( *p != '\0' && p < ( buf + len ) )
  148. {
  149. if( *p == '\\' )
  150. {
  151. p++;
  152. p++;
  153. continue;
  154. }
  155. if( *p == ':' )
  156. {
  157. if( p + 1 < buf + len )
  158. {
  159. cur = p + 1;
  160. TEST_HELPER_ASSERT( cnt < params_len );
  161. params[cnt++] = cur;
  162. }
  163. *p = '\0';
  164. }
  165. p++;
  166. }
  167. /* Replace newlines, question marks and colons in strings */
  168. for( i = 0; i < cnt; i++ )
  169. {
  170. p = params[i];
  171. q = params[i];
  172. while( *p != '\0' )
  173. {
  174. if( *p == '\\' && *( p + 1 ) == 'n' )
  175. {
  176. p += 2;
  177. *( q++ ) = '\n';
  178. }
  179. else if( *p == '\\' && *( p + 1 ) == ':' )
  180. {
  181. p += 2;
  182. *( q++ ) = ':';
  183. }
  184. else if( *p == '\\' && *( p + 1 ) == '?' )
  185. {
  186. p += 2;
  187. *( q++ ) = '?';
  188. }
  189. else
  190. *( q++ ) = *( p++ );
  191. }
  192. *q = '\0';
  193. }
  194. return( cnt );
  195. }
  196. /**
  197. * \brief Converts parameters into test function consumable parameters.
  198. * Example: Input: {"int", "0", "char*", "Hello",
  199. * "hex", "abef", "exp", "1"}
  200. * Output: {
  201. * 0, // Verified int
  202. * "Hello", // Verified string
  203. * 2, { 0xab, 0xef },// Converted len,hex pair
  204. * 9600 // Evaluated expression
  205. * }
  206. *
  207. *
  208. * \param cnt Parameter array count.
  209. * \param params Out array of found parameters.
  210. * \param int_params_store Memory for storing processed integer parameters.
  211. *
  212. * \return 0 for success else 1
  213. */
  214. static int convert_params( size_t cnt , char ** params , int * int_params_store )
  215. {
  216. char ** cur = params;
  217. char ** out = params;
  218. int ret = DISPATCH_TEST_SUCCESS;
  219. while ( cur < params + cnt )
  220. {
  221. char * type = *cur++;
  222. char * val = *cur++;
  223. if ( strcmp( type, "char*" ) == 0 )
  224. {
  225. if ( verify_string( &val ) == 0 )
  226. {
  227. *out++ = val;
  228. }
  229. else
  230. {
  231. ret = ( DISPATCH_INVALID_TEST_DATA );
  232. break;
  233. }
  234. }
  235. else if ( strcmp( type, "int" ) == 0 )
  236. {
  237. if ( verify_int( val, int_params_store ) == 0 )
  238. {
  239. *out++ = (char *) int_params_store++;
  240. }
  241. else
  242. {
  243. ret = ( DISPATCH_INVALID_TEST_DATA );
  244. break;
  245. }
  246. }
  247. else if ( strcmp( type, "hex" ) == 0 )
  248. {
  249. if ( verify_string( &val ) == 0 )
  250. {
  251. *int_params_store = mbedtls_test_unhexify(
  252. (unsigned char *) val, val );
  253. *out++ = val;
  254. *out++ = (char *)(int_params_store++);
  255. }
  256. else
  257. {
  258. ret = ( DISPATCH_INVALID_TEST_DATA );
  259. break;
  260. }
  261. }
  262. else if ( strcmp( type, "exp" ) == 0 )
  263. {
  264. int exp_id = strtol( val, NULL, 10 );
  265. if ( get_expression ( exp_id, int_params_store ) == 0 )
  266. {
  267. *out++ = (char *)int_params_store++;
  268. }
  269. else
  270. {
  271. ret = ( DISPATCH_INVALID_TEST_DATA );
  272. break;
  273. }
  274. }
  275. else
  276. {
  277. ret = ( DISPATCH_INVALID_TEST_DATA );
  278. break;
  279. }
  280. }
  281. return( ret );
  282. }
  283. /**
  284. * \brief Tests snprintf implementation with test input.
  285. *
  286. * \note
  287. * At high optimization levels (e.g. gcc -O3), this function may be
  288. * inlined in run_test_snprintf. This can trigger a spurious warning about
  289. * potential misuse of snprintf from gcc -Wformat-truncation (observed with
  290. * gcc 7.2). This warning makes tests in run_test_snprintf redundant on gcc
  291. * only. They are still valid for other compilers. Avoid this warning by
  292. * forbidding inlining of this function by gcc.
  293. *
  294. * \param n Buffer test length.
  295. * \param ref_buf Expected buffer.
  296. * \param ref_ret Expected snprintf return value.
  297. *
  298. * \return 0 for success else 1
  299. */
  300. #if defined(__GNUC__)
  301. __attribute__((__noinline__))
  302. #endif
  303. static int test_snprintf( size_t n, const char *ref_buf, int ref_ret )
  304. {
  305. int ret;
  306. char buf[10] = "xxxxxxxxx";
  307. const char ref[10] = "xxxxxxxxx";
  308. if( n >= sizeof( buf ) )
  309. return( -1 );
  310. ret = mbedtls_snprintf( buf, n, "%s", "123" );
  311. if( ret < 0 || (size_t) ret >= n )
  312. ret = -1;
  313. if( strncmp( ref_buf, buf, sizeof( buf ) ) != 0 ||
  314. ref_ret != ret ||
  315. memcmp( buf + n, ref + n, sizeof( buf ) - n ) != 0 )
  316. {
  317. return( 1 );
  318. }
  319. return( 0 );
  320. }
  321. /**
  322. * \brief Tests snprintf implementation.
  323. *
  324. * \param none
  325. *
  326. * \return 0 for success else 1
  327. */
  328. static int run_test_snprintf( void )
  329. {
  330. return( test_snprintf( 0, "xxxxxxxxx", -1 ) != 0 ||
  331. test_snprintf( 1, "", -1 ) != 0 ||
  332. test_snprintf( 2, "1", -1 ) != 0 ||
  333. test_snprintf( 3, "12", -1 ) != 0 ||
  334. test_snprintf( 4, "123", 3 ) != 0 ||
  335. test_snprintf( 5, "123", 3 ) != 0 );
  336. }
  337. /**
  338. * \brief Desktop implementation of execute_tests().
  339. * Parses command line and executes tests from
  340. * supplied or default data file.
  341. *
  342. * \param argc Command line argument count.
  343. * \param argv Argument array.
  344. *
  345. * \return Program exit status.
  346. */
  347. int execute_tests( int argc , const char ** argv )
  348. {
  349. /* Local Configurations and options */
  350. const char *default_filename = "DATA_FILE";
  351. const char *test_filename = NULL;
  352. const char **test_files = NULL;
  353. size_t testfile_count = 0;
  354. int option_verbose = 0;
  355. size_t function_id = 0;
  356. /* Other Local variables */
  357. int arg_index = 1;
  358. const char *next_arg;
  359. size_t testfile_index, i, cnt;
  360. int ret;
  361. unsigned total_errors = 0, total_tests = 0, total_skipped = 0;
  362. FILE *file;
  363. char buf[5000];
  364. char *params[50];
  365. /* Store for proccessed integer params. */
  366. int int_params[50];
  367. void *pointer;
  368. #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  369. int stdout_fd = -1;
  370. #endif /* __unix__ || __APPLE__ __MACH__ */
  371. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
  372. !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
  373. unsigned char alloc_buf[1000000];
  374. mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
  375. #endif
  376. #if defined(MBEDTLS_TEST_MUTEX_USAGE)
  377. mbedtls_test_mutex_usage_init( );
  378. #endif
  379. /*
  380. * The C standard doesn't guarantee that all-bits-0 is the representation
  381. * of a NULL pointer. We do however use that in our code for initializing
  382. * structures, which should work on every modern platform. Let's be sure.
  383. */
  384. memset( &pointer, 0, sizeof( void * ) );
  385. if( pointer != NULL )
  386. {
  387. mbedtls_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" );
  388. return( 1 );
  389. }
  390. /*
  391. * Make sure we have a snprintf that correctly zero-terminates
  392. */
  393. if( run_test_snprintf() != 0 )
  394. {
  395. mbedtls_fprintf( stderr, "the snprintf implementation is broken\n" );
  396. return( 1 );
  397. }
  398. while( arg_index < argc )
  399. {
  400. next_arg = argv[arg_index];
  401. if( strcmp( next_arg, "--verbose" ) == 0 ||
  402. strcmp( next_arg, "-v" ) == 0 )
  403. {
  404. option_verbose = 1;
  405. }
  406. else if( strcmp(next_arg, "--help" ) == 0 ||
  407. strcmp(next_arg, "-h" ) == 0 )
  408. {
  409. mbedtls_fprintf( stdout, USAGE );
  410. mbedtls_exit( EXIT_SUCCESS );
  411. }
  412. else
  413. {
  414. /* Not an option, therefore treat all further arguments as the file
  415. * list.
  416. */
  417. test_files = &argv[ arg_index ];
  418. testfile_count = argc - arg_index;
  419. }
  420. arg_index++;
  421. }
  422. /* If no files were specified, assume a default */
  423. if ( test_files == NULL || testfile_count == 0 )
  424. {
  425. test_files = &default_filename;
  426. testfile_count = 1;
  427. }
  428. /* Initialize the struct that holds information about the last test */
  429. memset( &test_info, 0, sizeof( test_info ) );
  430. /* Now begin to execute the tests in the testfiles */
  431. for ( testfile_index = 0;
  432. testfile_index < testfile_count;
  433. testfile_index++ )
  434. {
  435. size_t unmet_dep_count = 0;
  436. int unmet_dependencies[20];
  437. int missing_unmet_dependencies = 0;
  438. test_filename = test_files[ testfile_index ];
  439. file = fopen( test_filename, "r" );
  440. if( file == NULL )
  441. {
  442. mbedtls_fprintf( stderr, "Failed to open test file: %s\n",
  443. test_filename );
  444. return( 1 );
  445. }
  446. while( !feof( file ) )
  447. {
  448. if( unmet_dep_count > 0 )
  449. {
  450. mbedtls_fprintf( stderr,
  451. "FATAL: Dep count larger than zero at start of loop\n" );
  452. mbedtls_exit( MBEDTLS_EXIT_FAILURE );
  453. }
  454. unmet_dep_count = 0;
  455. missing_unmet_dependencies = 0;
  456. if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
  457. break;
  458. mbedtls_fprintf( stdout, "%s%.66s",
  459. test_info.result == TEST_RESULT_FAILED ? "\n" : "", buf );
  460. mbedtls_fprintf( stdout, " " );
  461. for( i = strlen( buf ) + 1; i < 67; i++ )
  462. mbedtls_fprintf( stdout, "." );
  463. mbedtls_fprintf( stdout, " " );
  464. fflush( stdout );
  465. total_tests++;
  466. if( ( ret = get_line( file, buf, sizeof( buf ) ) ) != 0 )
  467. break;
  468. cnt = parse_arguments( buf, strlen( buf ), params,
  469. sizeof( params ) / sizeof( params[0] ) );
  470. if( strcmp( params[0], "depends_on" ) == 0 )
  471. {
  472. for( i = 1; i < cnt; i++ )
  473. {
  474. int dep_id = strtol( params[i], NULL, 10 );
  475. if( dep_check( dep_id ) != DEPENDENCY_SUPPORTED )
  476. {
  477. if( unmet_dep_count <
  478. ARRAY_LENGTH( unmet_dependencies ) )
  479. {
  480. unmet_dependencies[unmet_dep_count] = dep_id;
  481. unmet_dep_count++;
  482. }
  483. else
  484. {
  485. missing_unmet_dependencies = 1;
  486. }
  487. }
  488. }
  489. if( ( ret = get_line( file, buf, sizeof( buf ) ) ) != 0 )
  490. break;
  491. cnt = parse_arguments( buf, strlen( buf ), params,
  492. sizeof( params ) / sizeof( params[0] ) );
  493. }
  494. // If there are no unmet dependencies execute the test
  495. if( unmet_dep_count == 0 )
  496. {
  497. test_info.result = TEST_RESULT_SUCCESS;
  498. test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_IDLE;
  499. #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  500. /* Suppress all output from the library unless we're verbose
  501. * mode
  502. */
  503. if( !option_verbose )
  504. {
  505. stdout_fd = redirect_output( stdout, "/dev/null" );
  506. if( stdout_fd == -1 )
  507. {
  508. /* Redirection has failed with no stdout so exit */
  509. exit( 1 );
  510. }
  511. }
  512. #endif /* __unix__ || __APPLE__ __MACH__ */
  513. function_id = strtoul( params[0], NULL, 10 );
  514. if ( (ret = check_test( function_id )) == DISPATCH_TEST_SUCCESS )
  515. {
  516. ret = convert_params( cnt - 1, params + 1, int_params );
  517. if ( DISPATCH_TEST_SUCCESS == ret )
  518. {
  519. ret = dispatch_test( function_id, (void **)( params + 1 ) );
  520. }
  521. }
  522. #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  523. if( !option_verbose && restore_output( stdout, stdout_fd ) )
  524. {
  525. /* Redirection has failed with no stdout so exit */
  526. exit( 1 );
  527. }
  528. #endif /* __unix__ || __APPLE__ __MACH__ */
  529. }
  530. if( unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE )
  531. {
  532. total_skipped++;
  533. mbedtls_fprintf( stdout, "----" );
  534. if( 1 == option_verbose && ret == DISPATCH_UNSUPPORTED_SUITE )
  535. {
  536. mbedtls_fprintf( stdout, "\n Test Suite not enabled" );
  537. }
  538. if( 1 == option_verbose && unmet_dep_count > 0 )
  539. {
  540. mbedtls_fprintf( stdout, "\n Unmet dependencies: " );
  541. for( i = 0; i < unmet_dep_count; i++ )
  542. {
  543. mbedtls_fprintf( stdout, "%d ",
  544. unmet_dependencies[i] );
  545. }
  546. if( missing_unmet_dependencies )
  547. mbedtls_fprintf( stdout, "..." );
  548. }
  549. mbedtls_fprintf( stdout, "\n" );
  550. fflush( stdout );
  551. unmet_dep_count = 0;
  552. missing_unmet_dependencies = 0;
  553. }
  554. else if( ret == DISPATCH_TEST_SUCCESS )
  555. {
  556. if( test_info.result == TEST_RESULT_SUCCESS )
  557. {
  558. mbedtls_fprintf( stdout, "PASS\n" );
  559. }
  560. else if( test_info.result == TEST_RESULT_SKIPPED )
  561. {
  562. mbedtls_fprintf( stdout, "----\n" );
  563. total_skipped++;
  564. }
  565. else
  566. {
  567. total_errors++;
  568. mbedtls_fprintf( stdout, "FAILED\n" );
  569. mbedtls_fprintf( stdout, " %s\n at line %d, %s\n",
  570. test_info.test, test_info.line_no,
  571. test_info.filename );
  572. }
  573. fflush( stdout );
  574. }
  575. else if( ret == DISPATCH_INVALID_TEST_DATA )
  576. {
  577. mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
  578. fclose( file );
  579. mbedtls_exit( 2 );
  580. }
  581. else if( ret == DISPATCH_TEST_FN_NOT_FOUND )
  582. {
  583. mbedtls_fprintf( stderr, "FAILED: FATAL TEST FUNCTION NOT FUND\n" );
  584. fclose( file );
  585. mbedtls_exit( 2 );
  586. }
  587. else
  588. total_errors++;
  589. }
  590. fclose( file );
  591. }
  592. mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
  593. if( total_errors == 0 )
  594. mbedtls_fprintf( stdout, "PASSED" );
  595. else
  596. mbedtls_fprintf( stdout, "FAILED" );
  597. mbedtls_fprintf( stdout, " (%u / %u tests (%u skipped))\n",
  598. total_tests - total_errors, total_tests, total_skipped );
  599. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
  600. !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
  601. #if defined(MBEDTLS_MEMORY_DEBUG)
  602. mbedtls_memory_buffer_alloc_status();
  603. #endif
  604. mbedtls_memory_buffer_alloc_free();
  605. #endif
  606. return( total_errors != 0 );
  607. }