Without this patch, building coreutils with
--enable-gcc-checking=expensive would fail with a message like
“lib/exclude.c:682:6: error: leak of FILE 'in' [CWE-775]
[-Werror=analyzer-file-leak]”, because Gnulib replaced fclose but
not fopen, and GCC saw a call to fopen followed by a call to
rpl_fclose.  The patch causes GCC to instead see a call to
rpl_fopen followed by rpl_fclose.
* m4/fclose.m4 (gl_FUNC_FCLOSE): Replace fopen when replacing
fclose.
* modules/fclose (Depends-on): Add fopen.
(configure.ac): Replace fopen when replacing fclose.
---
 ChangeLog      | 13 +++++++++++++
 m4/fclose.m4   |  4 ++++
 modules/fclose |  6 ++++++
 3 files changed, 23 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 972aec03db..8d39a64023 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2023-04-24  Paul Eggert  <egg...@cs.ucla.edu>
 
+       fclose: pacify gcc -Wanalyzer-file-leak
+       Without this patch, building coreutils with
+       --enable-gcc-checking=expensive would fail with a message like
+       “lib/exclude.c:682:6: error: leak of FILE 'in' [CWE-775]
+       [-Werror=analyzer-file-leak]”, because Gnulib replaced fclose but
+       not fopen, and GCC saw a call to fopen followed by a call to
+       rpl_fclose.  The patch causes GCC to instead see a call to
+       rpl_fopen followed by rpl_fclose.
+       * m4/fclose.m4 (gl_FUNC_FCLOSE): Replace fopen when replacing
+       fclose.
+       * modules/fclose (Depends-on): Add fopen.
+       (configure.ac): Replace fopen when replacing fclose.
+
        unsetenv-tests: pacify -Wanalyzer-putenv-of-auto-var
        * tests/test-unsetenv.c (main): Make entry static.  Even with this
        change, it’s unclear whether this test is portable POSIX code, but
diff --git a/m4/fclose.m4 b/m4/fclose.m4
index dc021dd9f3..74b7df0a77 100644
--- a/m4/fclose.m4
+++ b/m4/fclose.m4
@@ -31,6 +31,10 @@ AC_DEFUN([gl_FUNC_FCLOSE],
       *) REPLACE_FCLOSE=1 ;;
     esac
   fi
+
+  if test $REPLACE_FCLOSE = 1; then
+    REPLACE_FOPEN=1
+  fi
 ])
 
 dnl Determine whether fclose works on input streams.
diff --git a/modules/fclose b/modules/fclose
index 703de9e686..9a949e48b8 100644
--- a/modules/fclose
+++ b/modules/fclose
@@ -9,12 +9,18 @@ Depends-on:
 stdio
 close           [test $REPLACE_FCLOSE = 1]
 fflush          [test $REPLACE_FCLOSE = 1]
+fopen           [test $REPLACE_FCLOSE = 1]
 freading        [test $REPLACE_FCLOSE = 1]
 lseek           [test $REPLACE_FCLOSE = 1]
 msvc-inval      [test $REPLACE_FCLOSE = 1]
 
 configure.ac:
 gl_FUNC_FCLOSE
+if test $REPLACE_FCLOSE = 1; then
+  REPLACE_FOPEN=1
+  AC_LIBOBJ([fopen])
+  gl_PREREQ_FOPEN
+fi
 gl_CONDITIONAL([GL_COND_OBJ_FCLOSE], [test $REPLACE_FCLOSE = 1])
 gl_STDIO_MODULE_INDICATOR([fclose])
 
-- 
2.40.0


Reply via email to