Merge pull request #3164 from ronald-cron-arm/unmet-dependencies-buffer-overflow-fix-2.16

[backport 2.16] Unmet dependencies buffer overflow fix
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index ccd4d42..278de16 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -229,6 +229,40 @@
     mbedtls_exit( 1 );                                             \
 }
 
+#if defined(__GNUC__)
+/* Test if arg and &(arg)[0] have the same type. This is true if arg is
+ * an array but not if it's a pointer. */
+#define IS_ARRAY_NOT_POINTER( arg )                                     \
+    ( ! __builtin_types_compatible_p( __typeof__( arg ),                \
+                                      __typeof__( &( arg )[0] ) ) )
+#else
+/* On platforms where we don't know how to implement this check,
+ * omit it. Oh well, a non-portable check is better than nothing. */
+#define IS_ARRAY_NOT_POINTER( arg ) 1
+#endif
+
+/* A compile-time constant with the value 0. If `const_expr` is not a
+ * compile-time constant with a nonzero value, cause a compile-time error. */
+#define STATIC_ASSERT_EXPR( const_expr )                                \
+    ( 0 && sizeof( struct { int STATIC_ASSERT : 1 - 2 * ! ( const_expr ); } ) )
+/* Return the scalar value `value` (possibly promoted). This is a compile-time
+ * constant if `value` is. `condition` must be a compile-time constant.
+ * If `condition` is false, arrange to cause a compile-time error. */
+#define STATIC_ASSERT_THEN_RETURN( condition, value )   \
+    ( STATIC_ASSERT_EXPR( condition ) ? 0 : ( value ) )
+
+#define ARRAY_LENGTH_UNSAFE( array )            \
+    ( sizeof( array ) / sizeof( *( array ) ) )
+/** Return the number of elements of a static or stack array.
+ *
+ * \param array         A value of array (not pointer) type.
+ *
+ * \return The number of elements of the array.
+ */
+#define ARRAY_LENGTH( array )                                           \
+    ( STATIC_ASSERT_THEN_RETURN( IS_ARRAY_NOT_POINTER( array ),         \
+                                 ARRAY_LENGTH_UNSAFE( array ) ) )
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 26a7be4..5951e46 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -385,15 +385,16 @@
     const char *default_filename = "DATA_FILE";
     const char *test_filename = NULL;
     const char **test_files = NULL;
-    int testfile_count = 0;
+    size_t testfile_count = 0;
     int option_verbose = 0;
     int function_id = 0;
 
     /* Other Local variables */
     int arg_index = 1;
     const char *next_arg;
-    int testfile_index, ret, i, cnt;
-    int total_errors = 0, total_tests = 0, total_skipped = 0;
+    size_t testfile_index, i, cnt;
+    int ret;
+    unsigned total_errors = 0, total_tests = 0, total_skipped = 0;
     FILE *file;
     char buf[5000];
     char *params[50];
@@ -473,8 +474,9 @@
           testfile_index < testfile_count;
           testfile_index++ )
     {
-        int unmet_dep_count = 0;
+        size_t unmet_dep_count = 0;
         int unmet_dependencies[20];
+        int missing_unmet_dependencies = 0;
 
         test_filename = test_files[ testfile_index ];
 
@@ -495,6 +497,7 @@
                 mbedtls_exit( MBEDTLS_EXIT_FAILURE );
             }
             unmet_dep_count = 0;
+            missing_unmet_dependencies = 0;
 
             if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
                 break;
@@ -520,8 +523,16 @@
                     int dep_id = strtol( params[i], NULL, 10 );
                     if( dep_check( dep_id ) != DEPENDENCY_SUPPORTED )
                     {
-                        unmet_dependencies[unmet_dep_count] = dep_id;
-                        unmet_dep_count++;
+                        if( unmet_dep_count <
+                            ARRAY_LENGTH( unmet_dependencies ) )
+                        {
+                            unmet_dependencies[unmet_dep_count] = dep_id;
+                            unmet_dep_count++;
+                        }
+                        else
+                        {
+                            missing_unmet_dependencies = 1;
+                        }
                     }
                 }
 
@@ -590,11 +601,14 @@
                         mbedtls_fprintf( stdout, "%d ",
                                         unmet_dependencies[i] );
                     }
+                    if( missing_unmet_dependencies )
+                        mbedtls_fprintf( stdout, "..." );
                 }
                 mbedtls_fprintf( stdout, "\n" );
                 fflush( stdout );
 
                 unmet_dep_count = 0;
+                missing_unmet_dependencies = 0;
             }
             else if( ret == DISPATCH_TEST_SUCCESS )
             {
@@ -641,8 +655,8 @@
     else
         mbedtls_fprintf( stdout, "FAILED" );
 
-    mbedtls_fprintf( stdout, " (%d / %d tests (%d skipped))\n",
-             total_tests - total_errors, total_tests, total_skipped );
+    mbedtls_fprintf( stdout, " (%u / %u tests (%u skipped))\n",
+                     total_tests - total_errors, total_tests, total_skipped );
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
     !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)