Fix null pointer dereference in ScopedPrematureExitFile When TEST_PREMATURE_EXIT_FILE is set to a path that cannot be opened for writing (e.g., non-existent directory or insufficient permissions), posix::FOpen returns NULL. Previously, fwrite and fclose were called unconditionally on the result, causing a segmentation fault. This change: - Adds a null check before calling fwrite/fclose - Tracks whether the file was successfully created via a file_created_ flag, so the destructor only attempts removal when the file actually exists This matches the existing comment's stated intent that I/O errors should be silently ignored.

This commit is contained in:
Alvin Jaison 2026-07-23 09:24:19 +01:00
parent 08da6214b8
commit e331081278

View File

@ -5166,21 +5166,25 @@ class ScopedPrematureExitFile {
public: public:
explicit ScopedPrematureExitFile(const char* premature_exit_filepath) explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
: premature_exit_filepath_( : premature_exit_filepath_(
premature_exit_filepath ? premature_exit_filepath : "") { premature_exit_filepath ? premature_exit_filepath : ""),
file_created_(false) {
// If a path to the premature-exit file is specified... // If a path to the premature-exit file is specified...
if (!premature_exit_filepath_.empty()) { if (!premature_exit_filepath_.empty()) {
// create the file with a single "0" character in it. I/O // create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we // errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this. // don't want to fail the test because of this.
FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w"); FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w");
fwrite("0", 1, 1, pfile); if (pfile != nullptr) {
fclose(pfile); fwrite("0", 1, 1, pfile);
fclose(pfile);
file_created_ = true;
}
} }
} }
~ScopedPrematureExitFile() { ~ScopedPrematureExitFile() {
#ifndef GTEST_OS_ESP8266 #ifndef GTEST_OS_ESP8266
if (!premature_exit_filepath_.empty()) { if (file_created_) {
int retval = remove(premature_exit_filepath_.c_str()); int retval = remove(premature_exit_filepath_.c_str());
if (retval) { if (retval) {
GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \"" GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
@ -5193,6 +5197,7 @@ class ScopedPrematureExitFile {
private: private:
const std::string premature_exit_filepath_; const std::string premature_exit_filepath_;
bool file_created_;
ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete; ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete; ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;