From 270c2b8e863d0e75c3640e6a631e64ffcf8db16c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 30 Mar 2026 16:17:27 -0400 Subject: [PATCH] process: Don't duplicate NULL stdio handles on Windows. It's okay to pass null handles to win32's CreateProcess(). Fixes #14977. (cherry picked from commit f13cd9a666f8ab069dfa8d4700528243496be027) --- src/process/windows/SDL_windowsprocess.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/process/windows/SDL_windowsprocess.c b/src/process/windows/SDL_windowsprocess.c index 5c4bde8699..dfefa54f38 100644 --- a/src/process/windows/SDL_windowsprocess.c +++ b/src/process/windows/SDL_windowsprocess.c @@ -263,6 +263,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID HANDLE stdin_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE stdout_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE stderr_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; + HANDLE handle; DWORD pipe_mode = PIPE_NOWAIT; bool result = false; @@ -357,7 +358,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID break; case SDL_PROCESS_STDIO_INHERITED: default: - if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), + handle = GetStdHandle(STD_INPUT_HANDLE); + if (!handle) { + startup_info.hStdInput = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdInput = INVALID_HANDLE_VALUE; @@ -394,7 +398,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID break; case SDL_PROCESS_STDIO_INHERITED: default: - if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), + handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (!handle) { + startup_info.hStdOutput = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdOutput = INVALID_HANDLE_VALUE; @@ -405,7 +412,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID } if (redirect_stderr) { - if (!DuplicateHandle(GetCurrentProcess(), startup_info.hStdOutput, + handle = startup_info.hStdOutput; + if (!handle) { + startup_info.hStdError = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdError = INVALID_HANDLE_VALUE; @@ -440,7 +450,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID break; case SDL_PROCESS_STDIO_INHERITED: default: - if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), + handle = GetStdHandle(STD_ERROR_HANDLE); + if (!handle) { + startup_info.hStdError = NULL; + } else if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), &startup_info.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS)) { startup_info.hStdError = INVALID_HANDLE_VALUE;