From ead919d692f6f0e5069c75397b43d25bbe0bbf17 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Fri, 21 Feb 2025 22:30:51 +0100 Subject: [PATCH] tests/benchmark: Resolve (harmless) TOCTTOU .. that was reported by Coverity Scan. https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use --- expat/tests/benchmark/benchmark.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/expat/tests/benchmark/benchmark.c b/expat/tests/benchmark/benchmark.c index 70e39378..43ef9594 100644 --- a/expat/tests/benchmark/benchmark.c +++ b/expat/tests/benchmark/benchmark.c @@ -32,6 +32,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define _POSIX_C_SOURCE 1 // fdopen + +#if defined(_MSC_VER) +# include // _open, _close +#else +# include // close +#endif + +#include // open #include #include #include // ptrdiff_t @@ -61,6 +70,7 @@ int main(int argc, char *argv[]) { XML_Parser parser; char *XMLBuf, *XMLBufEnd, *XMLBufPtr; + int fd; FILE *file; struct stat fileAttr; int nrOfLoops, bufferSize, i, isFinal; @@ -82,13 +92,21 @@ main(int argc, char *argv[]) { if (argc != j + 4) return usage(argv[0], 1); - if (stat(argv[j + 1], &fileAttr) != 0) { + fd = open(argv[j + 1], O_RDONLY); + if (fd == -1) { + fprintf(stderr, "could not open file '%s'\n", argv[j + 1]); + return 2; + } + + if (fstat(fd, &fileAttr) != 0) { + close(fd); fprintf(stderr, "could not access file '%s'\n", argv[j + 1]); return 2; } - file = fopen(argv[j + 1], "r"); + file = fdopen(fd, "r"); if (! file) { + close(fd); fprintf(stderr, "could not open file '%s'\n", argv[j + 1]); return 2; } @@ -97,6 +115,7 @@ main(int argc, char *argv[]) { nrOfLoops = atoi(argv[j + 3]); if (bufferSize <= 0 || nrOfLoops <= 0) { fclose(file); + close(fd); fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n"); return 3; } @@ -104,6 +123,7 @@ main(int argc, char *argv[]) { XMLBuf = malloc(fileAttr.st_size); fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, file); fclose(file); + close(fd); if (ns) parser = XML_ParserCreateNS(NULL, '!');