Merge pull request #3936 from MarcZX100/codex/carry-fopen-s-output-null

fix(libc): clear fopen_s output on invalid arguments
This commit is contained in:
Dean 2026-10-13 02:32:30 +13:00 committed by GitHub
commit 57dc136026
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 1 deletions

View File

@ -177,7 +177,9 @@ FileStream* APS5_VABI fopen_nid_postfix(const char* filename, const char* mode)
int APS5_VABI fopen_s_nid_postfix(FileStream** result, const char* filename, const char* mode) {
constexpr int GuestEinval = 22;
constexpr int GuestEnoent = 2;
if (!result || !filename || !mode) return GuestEinval;
if (!result) return GuestEinval;
*result = nullptr;
if (!filename || !mode) return GuestEinval;
*result = fopen_nid_postfix(filename, mode);
return *result ? 0 : GuestEnoent;
}

View File

@ -10,6 +10,7 @@
extern "C" {
FileStream* APS5_VABI _ZSt7_FiopenPKcNSt5_IosbIiE9_OpenmodeEi_nid_postfix(const char*, int, int);
FileStream* APS5_VABI fopen_nid_postfix(const char*, const char*);
int APS5_VABI fopen_s_nid_postfix(FileStream**, const char*, const char*);
int APS5_VABI fclose_nid_postfix(FileStream*);
std::int64_t APS5_VABI ftello_nid_postfix(FileStream*);
}
@ -24,6 +25,8 @@ static void Check(bool value, int line) {
constexpr int In = 0x01, Out = 0x02, Ate = 0x04, App = 0x08, Trunc = 0x10, Nocreate = 0x20, Noreplace = 0x40,
Binary = 0x80;
constexpr int GuestEinval = 22;
constexpr int GuestEnoent = 2;
static FileStream* Open(const char* name, int mode) {
return _ZSt7_FiopenPKcNSt5_IosbIiE9_OpenmodeEi_nid_postfix(name, mode, 0x1b6);
@ -66,6 +69,21 @@ int main() {
Write(Open(file, Out), "abc");
Require(Contents(file) == "abc");
FileStream* checkedStream = &_Stdout_nid_postfix;
Require(fopen_s_nid_postfix(&checkedStream, nullptr, "rb") == GuestEinval);
Require(checkedStream == nullptr);
checkedStream = &_Stderr_nid_postfix;
Require(fopen_s_nid_postfix(&checkedStream, file, nullptr) == GuestEinval);
Require(checkedStream == nullptr);
Require(fopen_s_nid_postfix(nullptr, file, "rb") == GuestEinval);
checkedStream = &_Stdout_nid_postfix;
Require(fopen_s_nid_postfix(&checkedStream, file, "rb") == 0);
Require(checkedStream != nullptr);
Require(fclose_nid_postfix(checkedStream) == 0);
checkedStream = &_Stdout_nid_postfix;
Require(fopen_s_nid_postfix(&checkedStream, missing, "rb") == GuestEnoent);
Require(checkedStream == nullptr);
auto* stream = Open(file, In);
Require(stream != nullptr && std::fgetc(stream->GetHandle()) == 'a');
fclose_nid_postfix(stream);