From 02752ddf6a7ea316013f67c4a14d3625ee250cca Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 20 Aug 2024 01:15:53 -0400 Subject: [PATCH] don't leak memory when throwing an exception --- src/text_file_reader.cpp | 11 ++++++++++- unittest/commands/test_groups.cpp | 1 + unittest/formats/test_file_operations.cpp | 1 + unittest/formats/test_text_file_reader.cpp | 10 ++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/text_file_reader.cpp b/src/text_file_reader.cpp index 3cff7880a9..bc274e42fa 100644 --- a/src/text_file_reader.cpp +++ b/src/text_file_reader.cpp @@ -48,6 +48,7 @@ TextFileReader::TextFileReader(const std::string &filename, const std::string &f fp = fopen(filename.c_str(), "r"); if (fp == nullptr) { + delete[] line; throw FileReaderException( fmt::format("cannot open {} file {}: {}", filetype, filename, utils::getsyserror())); } @@ -74,7 +75,11 @@ TextFileReader::TextFileReader(FILE *fp, std::string filetype) : filetype(std::move(filetype)), closefp(false), line(nullptr), fp(fp), ignore_comments(true) { set_bufsize(1024); - if (fp == nullptr) throw FileReaderException("Invalid file descriptor"); + if (fp == nullptr) { + delete[] line; + line = nullptr; + throw FileReaderException("Invalid file descriptor"); + } } /** Closes the file */ @@ -90,6 +95,8 @@ TextFileReader::~TextFileReader() void TextFileReader::set_bufsize(int newsize) { if (newsize < 100) { + delete[] line; + line = nullptr; throw FileReaderException( fmt::format("line buffer size {} for {} file too small, must be > 100", newsize, filetype)); } @@ -112,6 +119,8 @@ void TextFileReader::skip_line() char *ptr = fgets(line, bufsize, fp); if (ptr == nullptr) { // EOF + delete[] line; + line = nullptr; throw EOFException(fmt::format("Missing line in {} file!", filetype)); } } diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index 4035a4a4d4..6900c527e0 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -229,6 +229,7 @@ TEST_F(GroupTest, SelectRestart) command("group five subtract all half xxx");); TEST_FAILURE(".*ERROR: Group ID xxx does not exist.*", command("group five intersect half top xxx");); + delete[] flags; } TEST_F(GroupTest, Molecular) diff --git a/unittest/formats/test_file_operations.cpp b/unittest/formats/test_file_operations.cpp index cd08650bf8..cd3b7dce68 100644 --- a/unittest/formats/test_file_operations.cpp +++ b/unittest/formats/test_file_operations.cpp @@ -232,6 +232,7 @@ TEST_F(FileOperationsTest, read_lines_from_file) rv = utils::read_lines_from_file(fp, 2, MAX_BUF_SIZE / 2, buf, me, world); ASSERT_EQ(rv, 1); delete[] buf; + if (me == 0) fclose(fp); } TEST_F(FileOperationsTest, logmesg) diff --git a/unittest/formats/test_text_file_reader.cpp b/unittest/formats/test_text_file_reader.cpp index 687f6539f0..3fae7ef231 100644 --- a/unittest/formats/test_text_file_reader.cpp +++ b/unittest/formats/test_text_file_reader.cpp @@ -87,6 +87,16 @@ TEST_F(TextFileReaderTest, nofp) ASSERT_THROW({ TextFileReader reader(nullptr, "test"); }, FileReaderException); } +TEST_F(TextFileReaderTest, buffer) +{ + test_files(); + auto *reader = new TextFileReader("text_reader_two.file", "test"); + reader->set_bufsize(4096); + auto *line = reader->next_line(); + ASSERT_THROW({ reader->set_bufsize(20); }, FileReaderException); + delete reader; +} + TEST_F(TextFileReaderTest, usefp) { test_files();