Skip to content

Fix: Allow SGR color space ID 0 to be valid#19768

Merged
DHowett merged 3 commits intomicrosoft:mainfrom
Vallabh-1504:main
Jan 23, 2026
Merged

Fix: Allow SGR color space ID 0 to be valid#19768
DHowett merged 3 commits intomicrosoft:mainfrom
Vallabh-1504:main

Conversation

@Vallabh-1504
Copy link
Contributor

Summary of the Pull Request

This PR fixes an issue where SGR color sequences containing a Color Space ID of 0 (e.g., \e[38:2:0:r:g:bm) were incorrectly rejected as invalid.

References and Relevant Issues

Closes #19547

Detailed Description of the Pull Request / Additional comments

The existing logic in adaptDispatchGraphics.cpp treats any non-empty Color Space ID as an invalid sequence, intended to catch malformed sequences where the Red component might be shifted.

However, according to ITU T.416, the Color Space ID parameter is defined, and a value of 0 is implementation-defined. It is widely accepted by other terminal emulators (like XTerm) as the default RGB color space. This change modifies the check to explicitly allow an ID of 0 while still rejecting other non-standard IDs, ensuring compatibility with tools that emit fully qualified T.416 sequences.

Validation Steps Performed

Verified manually in WSL/Bash using printf to send the specific SGR sequence.

Test Command: printf "\e[38:2:0:255:0:0mRED\e[m\n"

Result: The text now correctly renders in Red instead of the default foreground color.
Before:
Screenshot 2026-01-22 212609
After:
Screenshot 2026-01-22 212638

PR Checklist

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j4james does this seem right to you?

@DHowett
Copy link
Member

DHowett commented Jan 22, 2026

Oh, nevermind - you're the one who filed the original bug. Of course it seems right--your expertise is unparalleled here

Comment on lines +139 to +143
if (!hasColorSpaceId && red <= 255 && green <= 255 && blue <= 255)

// Allow the color if (No ID exists OR The ID is 0) AND colors are valid
bool validId = !hasColorSpaceId || (options.at(1).value() == 0);

if (validId && red <= 255 && green <= 255 && blue <= 255)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be simpler to just replace the hasColorSpaceId definition on line 131 with something like:

const bool validColorSpace = options.at(1).value_or(0) == 0;

Then you wouldn't need to define anything else here, since you could just test that variable as is.

We also need to update the comment on lines 128..130 to reflect the new behavior.

@Vallabh-1504
Copy link
Contributor Author

Hello, thanks for the suggestion! That is much cleaner. I have updated the logic to match your snippet.

(I applied this edit via the GitHub web editor as my local environment is currently rebuilding. I will keep an eye on the CI checks to ensure there are no formatting issues.)

@DHowett
Copy link
Member

DHowett commented Jan 23, 2026

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@DHowett DHowett enabled auto-merge (squash) January 23, 2026 16:25
@DHowett
Copy link
Member

DHowett commented Jan 23, 2026

@Vallabh-1504 thanks so much for doing this!

Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!

// some applications that support non-standard ODA color sequence might
// send the red value in its place.
const bool hasColorSpaceId = options.at(1).has_value();
const bool validColorSpace = options.at(1).value_or(0) == 0;
Copy link
Member

@lhecker lhecker Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably also work, and technically simpler for the CPU:

Suggested change
const bool validColorSpace = options.at(1).value_or(0) == 0;
const bool validColorSpace = options.at(1).value() <= 0;

This is because we store unset parameters with a value of -1. If you check the definition of value_or(0) you'll see that it actually translates to _value < 0 ? 0 : _value. In practice this difference will not matter the slightest (<1ns).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh. I prefer not leaking the implementation details of VTParameter

@DHowett DHowett merged commit c8549be into microsoft:main Jan 23, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ITU/ODA colors with a zero color space don't work

4 participants