Skip to content

Commit b3eba30

Browse files
authored
Fixed a bug where invalid open mode was not handled correctly. (#168)
For some `std::ios::openmode` flags, the resulting mode string was `nullptr` and was not checked before calling `fopen`
1 parent 85aaa1d commit b3eba30

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/create.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,17 @@ std::pair<fs::path, filebuf> create_file(std::string_view label,
197197
mode |= std::ios::in | std::ios::out;
198198

199199
#ifdef _WIN32
200+
std::FILE* handle;
201+
200202
// FIXME: use _wfopen_s
201-
std::FILE* handle = _wfopen(path.c_str(), make_mdstring(mode));
202-
if (handle == nullptr) {
203-
ec = std::error_code(errno, std::system_category());
203+
if (const wchar_t* mdstr = make_mdstring(mode)) {
204+
handle = _wfopen(path.c_str(), mdstr);
205+
if (handle == nullptr) {
206+
ec = std::error_code(errno, std::system_category());
207+
return {};
208+
}
209+
} else {
210+
ec = std::make_error_code(std::errc::invalid_argument);
204211
return {};
205212
}
206213
#else

tests/file.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,14 @@ TEST(file, create_invalid_extension) {
127127
EXPECT_THROW(file("", "/."), std::invalid_argument);
128128
}
129129

130-
/// Tests that file add std::ios::in and std::ios::out flags
130+
/// Tests error handling with invalid open mode
131+
TEST(file, create_invalid_openmode) {
132+
// C++ standard forbids opening a filebuf with `trunc | app`
133+
std::ios::openmode openmode = std::ios::trunc | std::ios::app;
134+
EXPECT_THROW(file("", "", openmode), fs::filesystem_error);
135+
}
136+
137+
/// Tests that file adds std::ios::in and std::ios::out flags
131138
TEST(file, ios_flags) {
132139
file tmpfile = file("", "", std::ios::binary);
133140
tmpfile << "Hello, world!" << std::flush;

0 commit comments

Comments
 (0)