From 917ba5890cf34cef9dcbf1477339c1b0caaaaf24 Mon Sep 17 00:00:00 2001 From: ymdatta Date: Fri, 23 Aug 2024 07:56:05 -0400 Subject: [PATCH] r.out.png: fix consecutive fclose calls on same pointer (#4214) This patch fixes two issues: 1. In one of the code paths, we are calling fclose on a file pointer which could potentially be NULL. Doing that would lead to undefined behavior. Check if a file pointer is NULL before closing it. 2. If we call fclose on same file pointer twice, in the second instance we could be closing file descriptor allocated to some other file, which typically happens to a freed descriptor. This issue was found by using cppcheck tool. Signed-off-by: Mohana Datta Yelugoti --- raster/r.out.png/main.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/raster/r.out.png/main.c b/raster/r.out.png/main.c index 2bc826fac59..4d3895e5d9f 100644 --- a/raster/r.out.png/main.c +++ b/raster/r.out.png/main.c @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) int png_compr, /* ret, */ do_alpha; struct Cell_head win; FILEDESC cellfile = 0; - FILE *fp; + FILE *fp = NULL; /* now goes from pnmtopng.c* -A.Sh */ /* @@ -207,20 +207,29 @@ int main(int argc, char *argv[]) png_create_write_struct(PNG_LIBPNG_VER_STRING, &pnmtopng_jmpbuf_struct, pnmtopng_error_handler, NULL); if (png_ptr == NULL) { - fclose(fp); + if (fp) { + fclose(fp); + fp = NULL; + } G_fatal_error("cannot allocate LIBPNG structure"); } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - fclose(fp); + if (fp) { + fclose(fp); + fp = NULL; + } G_fatal_error("cannot allocate LIBPNG structure"); } if (setjmp(pnmtopng_jmpbuf_struct.jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); + if (fp) { + fclose(fp); + fp = NULL; + } G_fatal_error("setjmp returns error condition (1)"); } @@ -360,7 +369,8 @@ int main(int argc, char *argv[]) /* G_free (info_ptr); */ png_destroy_write_struct(&png_ptr, &info_ptr); /* al 11/2000 */ - fclose(fp); + if (fp) + fclose(fp); if (wld_flag->answer) { if (do_stdout)