Order of environment variables different in WT #12667

Closed
opened 2026-01-31 03:21:35 +00:00 by claunia · 12 comments
Owner

Originally created by @vefatica on GitHub (Feb 20, 2021).

Environment

Microsoft Windows 10 Pro for Workstations
10.0.19042.804 (2009, 20H2)
Windows Terminal Preview
Version: 1.6.10412.0

Windows build number: [run `[Environment]::OSVersion` for powershell, or `ver` for cmd]
Windows Terminal version (if applicable):

Any other software?

Steps to reproduce

See below.

Expected behavior

Same behavior whether in WT or not

Actual behavior

Behavior different and undesirable when in WT.

In my three Windows shells (CMD, Powershell, TCC), when running in WT

  1. the environment block is ordered differently, and
  2. new environment variables seem to go in the wrong place

Here's a new CMD.EXE running in a Windows console; this is expected behavior.

image

And here's a new CMD.EXE running in Windows Terminal. Note that the variables __VIP (from the user environment) and WT (newly created) are out of place.

image

Originally created by @vefatica on GitHub (Feb 20, 2021). <!-- 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING: 1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement. 2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement. 3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number). 4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement. 5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement. All good? Then proceed! --> <!-- This bug tracker is monitored by Windows Terminal development team and other technical folks. **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue. If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link. Please use this form and describe your issue, concisely but precisely, with as much detail as possible. --> # Environment Microsoft Windows 10 Pro for Workstations 10.0.19042.804 (2009, 20H2) Windows Terminal Preview Version: 1.6.10412.0 ```none Windows build number: [run `[Environment]::OSVersion` for powershell, or `ver` for cmd] Windows Terminal version (if applicable): Any other software? ``` # Steps to reproduce <!-- A description of how to trigger this bug. --> See below. # Expected behavior Same behavior whether in WT or not <!-- A description of what you're expecting, possibly containing screenshots or reference material. --> # Actual behavior Behavior different and undesirable when in WT. <!-- What's actually happening? --> In my three Windows shells (CMD, Powershell, TCC), when running in WT 1. the environment block is ordered differently, and 2. new environment variables seem to go in the wrong place Here's a new CMD.EXE running in a Windows console; this is expected behavior. ![image](https://user-images.githubusercontent.com/61856645/108604119-d2372b00-7379-11eb-8afc-8be4a6879d12.png) And here's a new CMD.EXE running in Windows Terminal. Note that the variables __VIP (from the user environment) and WT (newly created) are out of place. ![image](https://user-images.githubusercontent.com/61856645/108604182-335efe80-737a-11eb-9055-ad68560f7ee4.png)
Author
Owner

@DHowett commented on GitHub (Feb 20, 2021):

I do not believe that the order of environment variables is a contract anybody needs to uphold. WT requests that the system generate a new environment block for every new subprocess, so this is the order returned by the system.

@DHowett commented on GitHub (Feb 20, 2021): I do not believe that the order of environment variables is a contract anybody needs to uphold. WT requests that the system generate a new environment block for every new subprocess, so this is the order returned by the system.
Author
Owner

@DHowett commented on GitHub (Feb 20, 2021):

I'm marking this "Won't Fix". If you can provide a reason why this matters to any software, I'll be happy to reopen it 😄

@DHowett commented on GitHub (Feb 20, 2021): I'm marking this "Won't Fix". If you can provide a reason why this _matters_ to any software, I'll be happy to reopen it :smile:
Author
Owner

@eryksun commented on GitHub (Feb 20, 2021):

See Changing Environment Variables:

All strings in the environment block must be sorted alphabetically by name. The sort is case-insensitive, Unicode order, without regard to locale. Because the equal sign is a separator, it must not be used in the name of an environment variable.

One aspect left unstated by the above quote is that the case-insensitive comparison converts to uppercase. For example, 'A' (ordinal 65) and 'a' (ordinal 97) should sort before '_' (ordinal 95).

An incorrect order may cause GetEnvironmentVariableW and SetEnvironmentVariableW to misbehave, if they assume a particular sorted order when searching for and inserting variables. Hopefully they're more robust than that nowadays.

Windows Terminal calls _wcsicmp, which is locale based (limited to ASCII A-Z in the "C" locale) and converts to lowercase. The expected sort order is possible using CompareStringOrdinal.

@eryksun commented on GitHub (Feb 20, 2021): See [Changing Environment Variables](https://docs.microsoft.com/en-us/windows/win32/procthread/changing-environment-variables): > All strings in the environment block must be sorted alphabetically by name. The sort is case-insensitive, Unicode order, without regard to locale. Because the equal sign is a separator, it must not be used in the name of an environment variable. One aspect left unstated by the above quote is that the case-insensitive comparison converts to uppercase. For example, `'A'` (ordinal 65) and `'a'` (ordinal 97) should sort before `'_'` (ordinal 95). An incorrect order may cause `GetEnvironmentVariableW` and `SetEnvironmentVariableW` to misbehave, if they assume a particular sorted order when searching for and inserting variables. Hopefully they're more robust than that nowadays. Windows Terminal [calls](https://github.com/microsoft/terminal/blob/ae550e0969595f062b15c2ff5cc33d4afe8ebc3f/src/types/inc/Environment.hpp) `_wcsicmp`, which is locale based (limited to ASCII A-Z in the "C" locale) and converts to lowercase. The expected sort order is possible using [`CompareStringOrdinal`](https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal).
Author
Owner

@eryksun commented on GitHub (Feb 20, 2021):

so this is the order returned by the system.

To be clear, it is not the order that CreateEnvironmentBlock returns. As shown by vefatica, it is also not the order used by SetEnvironmentVariableW, which inserts WT before __VIP in accordance with the expected uppercase, non-linguistic sort order.

@eryksun commented on GitHub (Feb 20, 2021): > so this is the order returned by the system. To be clear, it is not the order that `CreateEnvironmentBlock` returns. As shown by vefatica, it is also not the order used by `SetEnvironmentVariableW`, which inserts `WT` before `__VIP` in accordance with the expected uppercase, non-linguistic sort order.
Author
Owner

@vefatica commented on GitHub (Feb 20, 2021):

The behavior I mentioned seems to conflict with the documentation mentioned by @eryksun.

I don't know about upholding contracts, but what about tradition ... programs working as thay have for decades?

This just plain looks bad.

image

As for

why this matters

it makes environment variables hard to find when they're not where they're expected to be (and where they belong) in the list.

@vefatica commented on GitHub (Feb 20, 2021): The behavior I mentioned seems to conflict with the documentation mentioned by @eryksun. I don't know about upholding contracts, but what about tradition ... programs working as thay have for decades? This just plain looks bad. ![image](https://user-images.githubusercontent.com/61856645/108608934-57313d00-7398-11eb-83e0-dd565c406cc2.png) As for > why this matters it makes environment variables hard to find when they're not where they're expected to be (and where they belong) in the list.
Author
Owner

@vefatica commented on GitHub (Feb 20, 2021):

I, too, have confirmed (as @eryksun alluded to) CreateEnvironmentBlock() puts __VIP at the end.

@vefatica commented on GitHub (Feb 20, 2021): I, too, have confirmed (as @eryksun alluded to) CreateEnvironmentBlock() puts __VIP at the end.
Author
Owner

@vefatica commented on GitHub (Feb 20, 2021):

Please reopen this issue.

@vefatica commented on GitHub (Feb 20, 2021): Please reopen this issue.
Author
Owner

@DHowett commented on GitHub (Feb 20, 2021):

Huh, wild.

@DHowett commented on GitHub (Feb 20, 2021): Huh, wild.
Author
Owner

@vefatica commented on GitHub (Feb 20, 2021):

Thank you!

@vefatica commented on GitHub (Feb 20, 2021): Thank you!
Author
Owner

@zadjii-msft commented on GitHub (Mar 21, 2023):

This might've been fixed by #14999. We should double check. Maybe not, if we're still just dumping into an unordered map and then dumping back out.

Actually yea I'm gonna reckon it probably wasn't.

@zadjii-msft commented on GitHub (Mar 21, 2023): ~This might've been fixed by #14999~. We should double check. Maybe not, if we're still just dumping into an unordered map and then dumping back out. Actually yea I'm gonna reckon it probably wasn't.
Author
Owner

@ianjoneill commented on GitHub (Apr 1, 2023):

This is fixed by #15082

image

@ianjoneill commented on GitHub (Apr 1, 2023): This is fixed by #15082 ![image](https://user-images.githubusercontent.com/5821575/229314392-5c543fa3-add3-43f8-b173-16f1f92c77d9.png)
Author
Owner

@ianjoneill commented on GitHub (Apr 1, 2023):

This might've been fixed by #14999. We should double check. Maybe not, if we're still just dumping into an unordered map and then dumping back out.

Actually yea I'm gonna reckon it probably wasn't.

The map was ordered, it was just ordered wrongly 🙂

@ianjoneill commented on GitHub (Apr 1, 2023): > ~This might've been fixed by #14999~. We should double check. Maybe not, if we're still just dumping into an unordered map and then dumping back out. > > Actually yea I'm gonna reckon it probably wasn't. The map was ordered, it was just ordered wrongly 🙂
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#12667