Skip to content

Commit

Permalink
Set LC_ALL=C before running ping process in Ping.Send() (#50696)
Browse files Browse the repository at this point in the history
* Add tests for ping command with locale environment variables.

* Set LC_ALL=C before running ping process.

ping command output is affected by locale environment variables.
This will cause an exception in ParsePingUtilityOutput().
Set LC_ALL=C to get the same output regardless of the environment variables.

Fix #50363.
  • Loading branch information
smdn committed Apr 8, 2021
1 parent 597a5bc commit d927fcb
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/libraries/System.Net.Ping/src/System.Net.Ping.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<Reference Include="System.Threading.ThreadPool" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
<Reference Include="System.Collections.Specialized" />
<Reference Include="System.Diagnostics.Process" />
<Reference Include="System.IO.FileSystem" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ private Process GetPingProcess(IPAddress address, byte[] buffer, int timeout, Pi
ProcessStartInfo psi = new ProcessStartInfo(pingExecutable, processArgs);
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
// Set LC_ALL=C to make sure to get ping output which is not affected by locale environment variables such as LANG and LC_MESSAGES.
psi.EnvironmentVariables["LC_ALL"] = "C";
return new Process() { StartInfo = psi };
}

Expand Down
69 changes: 69 additions & 0 deletions src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.DotNet.XUnitExtensions;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Net.Test.Common;
Expand Down Expand Up @@ -915,5 +916,73 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_ElevatedUnix(
});
}, localIpAddress.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose();
}

[PlatformSpecific(TestPlatforms.AnyUnix)]
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)]
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)]
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")]
[InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)]
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)]
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")]
public void SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL)
{
IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily);
if (localIpAddress == null)
{
// No local address for given address family.
return;
}

var remoteInvokeStartInfo = new ProcessStartInfo();

remoteInvokeStartInfo.EnvironmentVariables["LANG"] = envVar_LANG;
remoteInvokeStartInfo.EnvironmentVariables["LC_MESSAGES"] = envVar_LC_MESSAGES;
remoteInvokeStartInfo.EnvironmentVariables["LC_ALL"] = envVar_LC_ALL;

RemoteExecutor.Invoke(address =>
{
SendBatchPing(
(ping) => ping.Send(address, TestSettings.PingTimeout),
(pingReply) =>
{
PingResultValidator(pingReply, new IPAddress[] { IPAddress.Parse(address) }, null);
});
}, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose();
}

[PlatformSpecific(TestPlatforms.AnyUnix)]
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)]
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)]
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")]
[InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)]
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)]
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")]
public void SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL)
{
IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily);
if (localIpAddress == null)
{
// No local address for given address family.
return;
}

var remoteInvokeStartInfo = new ProcessStartInfo();

remoteInvokeStartInfo.EnvironmentVariables["LANG"] = envVar_LANG;
remoteInvokeStartInfo.EnvironmentVariables["LC_MESSAGES"] = envVar_LC_MESSAGES;
remoteInvokeStartInfo.EnvironmentVariables["LC_ALL"] = envVar_LC_ALL;

RemoteExecutor.Invoke(async address =>
{
await SendBatchPingAsync(
(ping) => ping.SendPingAsync(address),
(pingReply) =>
{
PingResultValidator(pingReply, new IPAddress[] { IPAddress.Parse(address) }, null);
});
}, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose();
}
}
}

0 comments on commit d927fcb

Please sign in to comment.