From db2c0ccae08d830b654b4db93e554ca98e6003c5 Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Wed, 6 Feb 2019 21:09:02 +0100 Subject: [PATCH] Fix fdc2e85: Double close of file handles When unpacking downloaded content, the downloaded .gz file was being opened with `fopen`, the OS file handle given to zlib, and then afterwards zlib told to close the file. But the `FILE *` object was never closed with `fclose`, meaning the stdio library would have a hanging file object, whose file handle was now invalid or referred to a different file. This caused asserts during shutdown with Microsoft's C library in debug mode. Fix this by properly duplicating the OS handle and `fclose`ing the `FILE *` object, before giving the handle to zlib. --- src/network/network_content.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index e998aaeaf1..551abb4420 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -404,10 +404,14 @@ static bool GunzipFile(const ContentInfo *ci) { #if defined(WITH_ZLIB) bool ret = true; + + /* Need to open the file with fopen() to support non-ASCII on Windows. */ FILE *ftmp = fopen(GetFullFilename(ci, true), "rb"); if (ftmp == NULL) return false; + /* Duplicate the handle, and close the FILE*, to avoid double-closing the handle later. */ + gzFile fin = gzdopen(dup(fileno(ftmp)), "rb"); + fclose(ftmp); - gzFile fin = gzdopen(fileno(ftmp), "rb"); FILE *fout = fopen(GetFullFilename(ci, false), "wb"); if (fin == NULL || fout == NULL) { @@ -444,14 +448,7 @@ static bool GunzipFile(const ContentInfo *ci) } } - if (fin != NULL) { - /* Closes ftmp too! */ - gzclose(fin); - } else if (ftmp != NULL) { - /* In case the gz stream was opened correctly this will - * be closed by gzclose. */ - fclose(ftmp); - } + if (fin != NULL) gzclose(fin); if (fout != NULL) fclose(fout); return ret;