-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Environment.GetEnvironmentVariables() should tolerate duplicate case-insensitive variable names #42029
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
@asklar This doesn't seem like a problem the runtime can solve properly. Which version of the environment variable is correct? What part of the runtime would we expect to handle this reconciliation process? I am really unclear how we could ever fix this issue in a way that is correct according to all parties. |
There's a horrible solution: call win32 |
Hi @AaronRobinsonMSFT |
@asklar Okay so let's accept this possible workaround - which I am not convinced will work for all scenarios. Where would this occur? Is the desire for the runtime on start up to sanitize it's own environment variables? |
yes, I think that would be reasonable, or if you want to be more pay-for-play, upon the first call to the Environment.GetEnvironmentVariable / GetEnvironmentVariables / ExpandEnvironmentVariables methods |
@rainersigwald @AaronRobinsonMSFT could you guys please re-triage this? right now it's marked as needs more info and question which neither seems correct. |
Tagging subscribers to this area: @eiriktsarpalis, @jeffhandley |
Stacktrace as reported in dotnet/msbuild#5726 (comment)
If I get this correctly the issue stems from the |
Tagging subscribers to this area: @eiriktsarpalis, @jeffhandley |
…e same Example: "NPM_CONFIG_CACHE=^" "npm_config_cache=^" fixes dotnet#42029
I've written a repro app and was able to reproduce it only for Full Framework, not Core. Since it's not a security issue, I am just going to close it as using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
namespace DuplicateEnvVars
{
class Program
{
static int Main(string[] args) => args.Length == 0 ? StartNewProcess() : PrintEnvVars();
private static int StartNewProcess()
{
var startInfo = new ProcessStartInfo()
{
FileName = Process.GetCurrentProcess().MainModule.FileName,
Arguments = "--printEnvVars"
};
#if NETFRAMEWORK
var caseSensitiveEnvVars = new Hashtable()
{
{ "NPM_CONFIG_CACHE", "^" },
{ "npm_config_cache", "^" },
};
startInfo.UseShellExecute = false;
startInfo.EnvironmentVariables
.GetType()
.GetField("contents", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(startInfo.EnvironmentVariables, caseSensitiveEnvVars);
#else
var caseSensitiveEnvVars = new Dictionary<string, string>(StringComparer.Ordinal)
{
{ "NPM_CONFIG_CACHE", "^" },
{ "npm_config_cache", "^" },
};
startInfo.Environment
.GetType()
.GetField("_contents", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(startInfo.Environment, caseSensitiveEnvVars);
#endif
using (var process = Process.Start(startInfo))
{
process.WaitForExit();
}
return 0;
}
private static int PrintEnvVars()
{
Console.WriteLine("Output of Environment.GetEnvironmentVariables():");
foreach (DictionaryEntry item in Environment.GetEnvironmentVariables())
{
Console.WriteLine($"\t{item.Key}={item.Value}");
}
Console.WriteLine("Output of new ProcessStartInfo().EnvironmentVariables:");
foreach (DictionaryEntry item in new ProcessStartInfo().EnvironmentVariables)
{
Console.WriteLine($"\t{item.Key}={item.Value}");
}
Console.WriteLine("Output ofnew ProcessStartInfo().Environment:");
foreach (KeyValuePair<string, string> item in new ProcessStartInfo().Environment)
{
Console.WriteLine($"\t{item.Key}={item.Value}");
}
return 0;
}
}
}
|
@adamsitnik This is currently affecting MSBuild.exe - without a fix to .net framework (or getting msbuild to move to .net core which includes moving Task DLLs to .net core, which seems unlikely in the foreseeable future), this will continue to crash. Could you please reconsider? |
@asklar the bar for taking changes to .NET Framework is very high -- it is also a lengthy and costly process. I do not think this would be successful. I recommend a fix to Yarn, or how it's configured, or a wrapper script that fixes the environment block, or perhaps continue the discussion with MSBuild (as it ships in the SDK which is easier to change - I am not offering an opinion on whether the change is right for MSBuild). |
It may not be a near term solution, but I am curious why it is unlikely. Do you own the code? Just pointing out that building against .NET Standard may simply "just work" and then you could use the same DLL's for both .NET Framework and .NET Core. |
@danmosemsft I don't own msbuild nor any of the Task DLLs being used, I'm just trying to get my C++ app builds to not fail when invoked from nodejs/yarn. |
I actually think this may be a question/request for the C++ team to use the .NET Core version of MSBuild during their build. I will let @rainersigwald confirm that. |
Description
Some tools like Yarn will spawn nodeJS via CreateProcess and pass an environment block that contains duplicated environment variables, e.g:
Windows doesn't do any checking of environment variables being duplicated in CreateProcess so the node.exe process gets created with the two names. Then in our case, MSBuild (a .net app) gets launched from within node.exe, which later launches CL.exe and other build tools, which break because they don't expect to get the same variable twice in the env block.
The environment block as exposed in
Process
should be cleaned up to remove duplicates (i.e. variables that appear more than once)Configuration
Windows 10, all .net versions, all archs.
Regression?
Other information
Related bugs:
actions/runner-images#1566
nodejs/node#35129
dotnet/msbuild#5726
The text was updated successfully, but these errors were encountered: