SetConsoleMode with an invalid mode leaves it tainted #18178

Closed
opened 2026-01-31 06:05:58 +00:00 by claunia · 4 comments
Owner

Originally created by @GustavoLCR on GitHub (Aug 14, 2022).

Windows Terminal version

1.15.2002.0

Windows build number

10.0.19044.0

Other Software

No response

Steps to reproduce

#include <stdio.h>
#include <windows.h>

int main() {
	DWORD initial_mode = 0;
	HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
	if (!GetConsoleMode(in, &initial_mode)) {
		puts("GetConsoleMode failed");
		return 1;
	}
	printf("0x%x\n", initial_mode);
	if (!SetConsoleMode(in, -1)) {
		puts("SetConsoleMode failed");
	};
	DWORD new_mode = 0;
	if (!GetConsoleMode(in, &new_mode)) {
		puts("GetConsoleMode failed");
		return 1;
	}
	printf("0x%x\n", new_mode);
	return new_mode != initial_mode;
}

Expected Behavior

Trying to set the console mode to an invalid value should fail and not change it.

Actual Behavior

Setting the console mode with an unsupported flag reports failure but still sets it.
This is unfortunate as it will cause all subsequent calls to SetConsoleMode with a value from GetConsoleMode to report failure.

Originally created by @GustavoLCR on GitHub (Aug 14, 2022). ### Windows Terminal version 1.15.2002.0 ### Windows build number 10.0.19044.0 ### Other Software _No response_ ### Steps to reproduce ```c #include <stdio.h> #include <windows.h> int main() { DWORD initial_mode = 0; HANDLE in = GetStdHandle(STD_INPUT_HANDLE); if (!GetConsoleMode(in, &initial_mode)) { puts("GetConsoleMode failed"); return 1; } printf("0x%x\n", initial_mode); if (!SetConsoleMode(in, -1)) { puts("SetConsoleMode failed"); }; DWORD new_mode = 0; if (!GetConsoleMode(in, &new_mode)) { puts("GetConsoleMode failed"); return 1; } printf("0x%x\n", new_mode); return new_mode != initial_mode; } ``` ### Expected Behavior Trying to set the console mode to an invalid value should fail and not change it. ### Actual Behavior Setting the console mode with an unsupported flag reports failure but still sets it. This is unfortunate as it will cause all subsequent calls to `SetConsoleMode` with a value from `GetConsoleMode` to report failure.
claunia added the Resolution-By-DesignIssue-BugNeeds-Tag-Fix labels 2026-01-31 06:05:59 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Aug 15, 2022):

Hmm. This kinda vaguely reminds me of #12077. I might need @DHowett's help to dedupe those though

@zadjii-msft commented on GitHub (Aug 15, 2022): Hmm. This kinda vaguely reminds me of #12077. I might need @DHowett's help to dedupe those though
Author
Owner

@DHowett commented on GitHub (Aug 16, 2022):

Trying to set the console mode to an invalid value should fail and not change it.

UNFORTUNATELY . . . this snippet of code is very relevant today.

1b3d004782/src/host/getset.cpp (L387-L400)

This is, therefore, by design. We have this hack to maintain compatibility with every version of PowerShell that's ever shipped... ☹️

@DHowett commented on GitHub (Aug 16, 2022): > Trying to set the console mode to an invalid value should fail and not change it. UNFORTUNATELY . . . this snippet of code is very relevant today. https://github.com/microsoft/terminal/blob/1b3d004782817ee6f36e37401853c2d25703976e/src/host/getset.cpp#L387-L400 This is, therefore, by design. We have this hack to maintain compatibility with every version of PowerShell that's ever shipped... ☹️
Author
Owner

@Gyross commented on GitHub (Aug 16, 2022):

Can we please have clearer documentation in MSDN on what the failure behaviour of these functions is? For instance:

  • It's not documented whether we need to set the buffer back to the original mode on failure.
  • It's not documented what error codes we can expect to get from GetLastError and whether it's even possible to handle them (it could be any of 16000 errors!).
  • It's not documented whether buffers and their modes persist when the program exits.

I understand the need to keep suboptimal behaviour because old versions of powershell were incorrect, but I need to know about it in advance so that I can make my programs correct.

@Gyross commented on GitHub (Aug 16, 2022): Can we please have clearer documentation in MSDN on what the failure behaviour of these functions is? For instance: - It's not documented whether we need to set the buffer back to the original mode on failure. - It's not documented what error codes we can expect to get from `GetLastError` and whether it's even possible to handle them (it could be any of 16000 errors!). - It's not documented whether buffers and their modes persist when the program exits. I understand the need to keep suboptimal behaviour because old versions of powershell were incorrect, but I need to know about it in advance so that I can make my programs correct.
Author
Owner

@zadjii-msft commented on GitHub (Aug 16, 2022):

Sure, I ported the body of that comment to an issue on the docs repo to make sure we don't lose track of it. Thanks!

@zadjii-msft commented on GitHub (Aug 16, 2022): Sure, I ported the body of that comment to an issue on the docs repo to make sure we don't lose track of it. Thanks!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#18178