-
Notifications
You must be signed in to change notification settings - Fork 930
Description
What You Are Seeing?
refreshenv.cmd doesn't correctly handle environment variables with a value that includes a "%" character.
I'm using Windows 10 and choco v0.10.8.
What is Expected?
I would like the environment variable value after a refreshenv to be the same as if I create a new process.
How Did You Get This To Happen? (Steps to Reproduce)
- start new cmd.exe
> setx test test%20value
(N.B. This creates a persistent environment variable. After testing, you may wish to remove it with the GUI or registry command as described here.)- start new cmd.exe
> set
- Observe that the value of variable
test
istest%20value
> refreshenv
> set
- Observe that the value of variable
test
istest0value
Output Log
I note that the refreshenv.cmd
uses a temporary file %TEMP%\_env.cmd
The script does delete some of the files that it creates in this folder, but not _env.cmd
, so it is possible to observe the contents of the file after running refreshenv
. In my case, the relevant line is
set "test=test%20value"
This seems ok, but the command processor is interpreting the %2
as a command line argument, so the final value of the variable is test0value
.
Thoughts about possible fixes
One possibility would be to replace all occurrences of % in the _env.cmd file with %% before calling the cmd file. It does seem to solve the current problem, but it appears to cause a problem: when I edit my path variable using the windows GUI, I see one entry which is %JAVA_HOME%\bin
. This variable is expanded by the system at some point, because when I run set
in my cmd.exe
window, the result does not show %JAVA_HOME%\bin
, it shows C:\Program Files\Java\jre1.8.0_181\bin
. If I naively replace all single % with %%, then the resulting path does not have that variable replaced. In my case, it might be possible to replace % with %% in all the non-path variables. But it's not clear that would work for other people, who may want variable expansion in non-path variables.
I'm not sure if there is a sensible way to distinguish between cases where the % should be quoted, and cases where it should not.
Another workaround I am considering is to store my environment variable value with %%:
setx test test%%20value
Then, when I look at the value in a fresh cmd.exe process, it will be test%%20value
. After refreshenv
, the value will be test%20value
.
My application that uses the value could then replace occurrences of %% with % before processing the value further.
For my application, where the value I'm storing is an encoded URL, I don't need to represent a real value that could have %% in it literally, so the replacement should be safe. But this doesn't seem safe in general.
Interested in peoples' thoughts.