Commit 2924476b55 for openssl.org

commit 2924476b5591e691e904c4baf57894c526c4b8de
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Wed Aug 19 13:54:30 2026 +0200

    test: forward real stdio calls in bss_file unit test mocks

    The --wrap link option rewrites the stdio symbols of everything linked
    into the test binary. In --coverage builds libgcov reads and writes the
    .gcda files at process exit through fread/fwrite/fseek/ftell/fclose,
    which then hit the cmocka mocks with no expectations queued and make
    the binary exit with 255 after all tests have passed. Forward calls on
    any stream other than the fake test pointers to the real functions.

    Assisted-by: Claude:claude-fable-5
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Reviewed-by: Bob Beck <beck@openssl.org>
    Merge-date: Thu Aug 20 07:50:12 2026
    Merged-from: https://github.com/openssl/openssl/pull/32431

diff --git a/test/unit/crypto/bio/test_bss_file.c b/test/unit/crypto/bio/test_bss_file.c
index 88388aeb3f..ccfa88d687 100644
--- a/test/unit/crypto/bio/test_bss_file.c
+++ b/test/unit/crypto/bio/test_bss_file.c
@@ -47,6 +47,30 @@ int __wrap_fclose(FILE *stream);
 int __wrap_fflush(FILE *stream);
 char *__wrap_fgets(char *s, int size, FILE *stream);

+size_t __real_fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t __real_fwrite(const void *ptr, size_t size, size_t nmemb,
+    FILE *stream);
+int __real_fseek(FILE *stream, long offset, int whence);
+long __real_ftell(FILE *stream);
+int __real_feof(FILE *stream);
+int __real_ferror(FILE *stream);
+int __real_fclose(FILE *stream);
+int __real_fflush(FILE *stream);
+char *__real_fgets(char *s, int size, FILE *stream);
+
+/*
+ * The --wrap link option rewrites the stdio calls of everything linked
+ * into the binary, not just of bss_file.c.  In particular libgcov in
+ * --coverage builds reads and writes the .gcda files at process exit
+ * through fread/fwrite/fseek/ftell/fclose, which must not hit the mocks.
+ * The tests only ever operate on the two fake FILE pointers, so calls on
+ * any other stream are forwarded to the real functions.
+ */
+static int is_mocked_fp(FILE *stream)
+{
+    return stream == FAKE_FP || stream == FAKE_FP2;
+}
+
 FILE *__wrap_openssl_fopen(const char *filename, const char *mode)
 {
     FILE *fp;
@@ -62,6 +86,8 @@ FILE *__wrap_openssl_fopen(const char *filename, const char *mode)

 size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_fread(ptr, size, nmemb, stream);
     function_called();
     check_expected_ptr(ptr);
     check_expected(size);
@@ -72,6 +98,8 @@ size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

 size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_fwrite(ptr, size, nmemb, stream);
     function_called();
     check_expected_ptr(ptr);
     check_expected(size);
@@ -82,6 +110,8 @@ size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

 int __wrap_fseek(FILE *stream, long offset, int whence)
 {
+    if (!is_mocked_fp(stream))
+        return __real_fseek(stream, offset, whence);
     function_called();
     check_expected_ptr(stream);
     check_expected(offset);
@@ -91,6 +121,8 @@ int __wrap_fseek(FILE *stream, long offset, int whence)

 long __wrap_ftell(FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_ftell(stream);
     function_called();
     check_expected_ptr(stream);
     return mock_type(long);
@@ -98,6 +130,8 @@ long __wrap_ftell(FILE *stream)

 int __wrap_feof(FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_feof(stream);
     function_called();
     check_expected_ptr(stream);
     return mock_type(int);
@@ -105,6 +139,8 @@ int __wrap_feof(FILE *stream)

 int __wrap_ferror(FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_ferror(stream);
     function_called();
     check_expected_ptr(stream);
     return mock_type(int);
@@ -112,6 +148,8 @@ int __wrap_ferror(FILE *stream)

 int __wrap_fclose(FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_fclose(stream);
     function_called();
     check_expected_ptr(stream);
     return mock_type(int);
@@ -119,6 +157,8 @@ int __wrap_fclose(FILE *stream)

 int __wrap_fflush(FILE *stream)
 {
+    if (!is_mocked_fp(stream))
+        return __real_fflush(stream);
     function_called();
     check_expected_ptr(stream);
     return mock_type(int);
@@ -128,6 +168,8 @@ char *__wrap_fgets(char *s, int size, FILE *stream)
 {
     const char *data;

+    if (!is_mocked_fp(stream))
+        return __real_fgets(s, size, stream);
     function_called();
     check_expected_ptr(s);
     check_expected(size);