diff --git a/src/Runner.Sdk/ProcessInvoker.cs b/src/Runner.Sdk/ProcessInvoker.cs index e46b2a057..de9804639 100644 --- a/src/Runner.Sdk/ProcessInvoker.cs +++ b/src/Runner.Sdk/ProcessInvoker.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; using GitHub.Runner.Sdk; +using System.Text.RegularExpressions; namespace GitHub.Runner.Sdk { @@ -265,8 +266,8 @@ namespace GitHub.Runner.Sdk foreach (KeyValuePair kvp in environment) { #if OS_WINDOWS - string tempKey = String.IsNullOrWhiteSpace(kvp.Key) ? kvp.Key : kvp.Key.Split('\0')[0]; - string tempValue = String.IsNullOrWhiteSpace(kvp.Value) ? kvp.Value : kvp.Value.Split('\0')[0]; + string tempKey = String.IsNullOrWhiteSpace(kvp.Key) ? kvp.Key : Regex.Split(kvp.Key, @"\p{C}")[0]; + string tempValue = String.IsNullOrWhiteSpace(kvp.Value) ? kvp.Value : Regex.Split(kvp.Value, @"\p{C}")[0]; if(!String.IsNullOrWhiteSpace(tempKey)) { _proc.StartInfo.Environment[tempKey] = tempValue; diff --git a/src/Test/L0/ProcessInvokerL0.cs b/src/Test/L0/ProcessInvokerL0.cs index 6d99932e3..cd958e2f9 100644 --- a/src/Test/L0/ProcessInvokerL0.cs +++ b/src/Test/L0/ProcessInvokerL0.cs @@ -164,6 +164,40 @@ namespace GitHub.Runner.Common.Tests } } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public async Task SetTestEnvWithTabInKey() + { + using (TestHostContext hc = new(this)) + { + Tracing trace = hc.GetTrace(); + + Int32 exitCode = -1; + var processInvoker = new ProcessInvokerWrapper(); + processInvoker.Initialize(hc); + var stdout = new List(); + var stderr = new List(); + processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => + { + trace.Info(e.Data); + stdout.Add(e.Data); + }; + processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) => + { + trace.Info(e.Data); + stderr.Add(e.Data); + }; + + exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"echo %TEST%\"", new Dictionary() { { "TEST\u0009second", "first" } }, CancellationToken.None); + + trace.Info("Exit Code: {0}", exitCode); + Assert.Equal(0, exitCode); + Assert.Equal("first", stdout.First(x => !string.IsNullOrWhiteSpace(x))); + + } + } + [Fact] [Trait("Level", "L0")] [Trait("Category", "Common")] @@ -197,6 +231,40 @@ namespace GitHub.Runner.Common.Tests } } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public async Task SetTestEnvWithTabInValue() + { + using (TestHostContext hc = new(this)) + { + Tracing trace = hc.GetTrace(); + + Int32 exitCode = -1; + var processInvoker = new ProcessInvokerWrapper(); + processInvoker.Initialize(hc); + var stdout = new List(); + var stderr = new List(); + processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => + { + trace.Info(e.Data); + stdout.Add(e.Data); + }; + processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) => + { + trace.Info(e.Data); + stderr.Add(e.Data); + }; + + exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"echo %TEST%\"", new Dictionary() { { "TEST", "first\u0009second" } }, CancellationToken.None); + + trace.Info("Exit Code: {0}", exitCode); + Assert.Equal(0, exitCode); + Assert.Equal("first", stdout.First(x => !string.IsNullOrWhiteSpace(x))); + + } + } #endif [Fact] [Trait("Level", "L0")]