From f13cd9a666f8ab069dfa8d4700528243496be027 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
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.
---
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 5c4bde869989f..dfefa54f3848b 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;