Skip to content

Execution of the refreshenv command incorrectly removes % (percent) characters from environment variable values #1664

@johnyesberg

Description

@johnyesberg

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 is test%20value
  • > refreshenv
  • > set
  • Observe that the value of variable test is test0value

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.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions