Skip to content

Commit d927fcb

Browse files
authored
Set LC_ALL=C before running ping process in Ping.Send() (#50696)
* 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.
1 parent 597a5bc commit d927fcb

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/libraries/System.Net.Ping/src/System.Net.Ping.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
<Reference Include="System.Threading.ThreadPool" />
103103
</ItemGroup>
104104
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
105+
<Reference Include="System.Collections.Specialized" />
105106
<Reference Include="System.Diagnostics.Process" />
106107
<Reference Include="System.IO.FileSystem" />
107108
</ItemGroup>

src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ private Process GetPingProcess(IPAddress address, byte[] buffer, int timeout, Pi
295295
ProcessStartInfo psi = new ProcessStartInfo(pingExecutable, processArgs);
296296
psi.RedirectStandardOutput = true;
297297
psi.RedirectStandardError = true;
298+
// 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.
299+
psi.EnvironmentVariables["LC_ALL"] = "C";
298300
return new Process() { StartInfo = psi };
299301
}
300302

src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using Microsoft.DotNet.XUnitExtensions;
5+
using System.Diagnostics;
56
using System.Linq;
67
using System.Net.Sockets;
78
using System.Net.Test.Common;
@@ -915,5 +916,73 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_ElevatedUnix(
915916
});
916917
}, localIpAddress.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose();
917918
}
919+
920+
[PlatformSpecific(TestPlatforms.AnyUnix)]
921+
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
922+
[InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)]
923+
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)]
924+
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")]
925+
[InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)]
926+
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)]
927+
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")]
928+
public void SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL)
929+
{
930+
IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily);
931+
if (localIpAddress == null)
932+
{
933+
// No local address for given address family.
934+
return;
935+
}
936+
937+
var remoteInvokeStartInfo = new ProcessStartInfo();
938+
939+
remoteInvokeStartInfo.EnvironmentVariables["LANG"] = envVar_LANG;
940+
remoteInvokeStartInfo.EnvironmentVariables["LC_MESSAGES"] = envVar_LC_MESSAGES;
941+
remoteInvokeStartInfo.EnvironmentVariables["LC_ALL"] = envVar_LC_ALL;
942+
943+
RemoteExecutor.Invoke(address =>
944+
{
945+
SendBatchPing(
946+
(ping) => ping.Send(address, TestSettings.PingTimeout),
947+
(pingReply) =>
948+
{
949+
PingResultValidator(pingReply, new IPAddress[] { IPAddress.Parse(address) }, null);
950+
});
951+
}, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose();
952+
}
953+
954+
[PlatformSpecific(TestPlatforms.AnyUnix)]
955+
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
956+
[InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)]
957+
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)]
958+
[InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")]
959+
[InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)]
960+
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)]
961+
[InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")]
962+
public void SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL)
963+
{
964+
IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily);
965+
if (localIpAddress == null)
966+
{
967+
// No local address for given address family.
968+
return;
969+
}
970+
971+
var remoteInvokeStartInfo = new ProcessStartInfo();
972+
973+
remoteInvokeStartInfo.EnvironmentVariables["LANG"] = envVar_LANG;
974+
remoteInvokeStartInfo.EnvironmentVariables["LC_MESSAGES"] = envVar_LC_MESSAGES;
975+
remoteInvokeStartInfo.EnvironmentVariables["LC_ALL"] = envVar_LC_ALL;
976+
977+
RemoteExecutor.Invoke(async address =>
978+
{
979+
await SendBatchPingAsync(
980+
(ping) => ping.SendPingAsync(address),
981+
(pingReply) =>
982+
{
983+
PingResultValidator(pingReply, new IPAddress[] { IPAddress.Parse(address) }, null);
984+
});
985+
}, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose();
986+
}
918987
}
919988
}

0 commit comments

Comments
 (0)