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