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