Skip to content

Commit 8a81194

Browse files
pranavkmPilchie
andauthored
Enables code analysis rules about culture sensitive string operations (#26656)
* Enable string comparison FxCop rules Co-authored-by: Kevin Pilch <[email protected]>
1 parent fe6a3fc commit 8a81194

File tree

409 files changed

+1619
-1205
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

409 files changed

+1619
-1205
lines changed

.editorconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ end_of_line = lf
4242

4343
[*.{razor,cshtml}]
4444
charset = utf-8-bom
45+
46+
[*.cs]
47+
dotnet_diagnostic.CA1304.severity = error
48+
dotnet_diagnostic.CA1305.severity = error
49+
dotnet_diagnostic.CA1310.severity = error

eng/tools/RepoTasks/.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[*.cs]
2+
dotnet_diagnostic.CA1307.severity = none
3+
dotnet_diagnostic.CA1308.severity = none
4+
dotnet_diagnostic.CA1309.severity = none

src/Analyzers/Analyzers/test/AnalyzerTestBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public abstract class AnalyzerTestBase
1313
{
1414
public TestSource Read(string source)
1515
{
16-
if (!source.EndsWith(".cs"))
16+
if (!source.EndsWith(".cs", StringComparison.Ordinal))
1717
{
1818
source = source + ".cs";
1919
}
@@ -30,7 +30,7 @@ public TestSource Read(string source)
3030

3131
public Project CreateProject(string source)
3232
{
33-
if (!source.EndsWith(".cs"))
33+
if (!source.EndsWith(".cs", StringComparison.Ordinal))
3434
{
3535
source = source + ".cs";
3636
}

src/Antiforgery/src/Internal/DefaultAntiforgery.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ private void LogCacheHeaderOverrideWarning(HttpResponse response)
400400
var pragmaHeader = response.Headers[HeaderNames.Pragma];
401401
if (!logWarning
402402
&& !string.IsNullOrEmpty(pragmaHeader)
403-
&& string.Compare(pragmaHeader, "no-cache", ignoreCase: true) != 0)
403+
&& !string.Equals(pragmaHeader, "no-cache", StringComparison.OrdinalIgnoreCase))
404404
{
405405
logWarning = true;
406406
}

src/Components/Analyzers/src/ComponentParametersShouldBePublicCodeFixProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Immutable;
55
using System.Composition;
6+
using System.Globalization;
67
using System.Linq;
78
using System.Threading.Tasks;
89
using Microsoft.CodeAnalysis;
@@ -37,7 +38,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
3738
var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<PropertyDeclarationSyntax>().First();
3839

3940
// Register a code action that will invoke the fix.
40-
var title = Title.ToString();
41+
var title = Title.ToString(CultureInfo.InvariantCulture);
4142
context.RegisterCodeFix(
4243
CodeAction.Create(
4344
title: title,

src/Components/Analyzers/test/AnalyzerTestBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public abstract class AnalyzerTestBase
1616

1717
public TestSource Read(string source)
1818
{
19-
if (!source.EndsWith(".cs"))
19+
if (!source.EndsWith(".cs", StringComparison.Ordinal))
2020
{
2121
source = source + ".cs";
2222
}
@@ -33,7 +33,7 @@ public TestSource Read(string source)
3333

3434
public Project CreateProject(string source)
3535
{
36-
if (!source.EndsWith(".cs"))
36+
if (!source.EndsWith(".cs", StringComparison.Ordinal))
3737
{
3838
source = source + ".cs";
3939
}

src/Components/Analyzers/test/Verifiers/CodeFixVerifier.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33

44
// Most of the code in this file comes from the default Roslyn Analyzer project template
55

6+
using System.Collections.Generic;
7+
using System.Globalization;
8+
using System.Linq;
9+
using System.Threading;
610
using Microsoft.CodeAnalysis;
711
using Microsoft.CodeAnalysis.CodeActions;
812
using Microsoft.CodeAnalysis.CodeFixes;
913
using Microsoft.CodeAnalysis.Diagnostics;
1014
using Microsoft.CodeAnalysis.Formatting;
11-
using System.Collections.Generic;
12-
using System.Linq;
13-
using System.Threading;
1415
using Xunit;
1516

1617
namespace TestHelper
@@ -82,7 +83,7 @@ private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProv
8283
var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
8384
var compilerDiagnostics = GetCompilerDiagnostics(document);
8485
var attempts = analyzerDiagnostics.Length;
85-
86+
8687
for (int i = 0; i < attempts; ++i)
8788
{
8889
var actions = new List<CodeAction>();
@@ -113,7 +114,9 @@ private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProv
113114
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
114115

115116
Assert.True(false,
116-
string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
117+
string.Format(
118+
CultureInfo.InvariantCulture,
119+
"Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
117120
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
118121
document.GetSyntaxRootAsync().Result.ToFullString()));
119122
}

src/Components/Analyzers/test/Verifiers/DiagnosticVerifier.cs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
// Most of the code in this file comes from the default Roslyn Analyzer project template
55

6-
using Microsoft.CodeAnalysis;
7-
using Microsoft.CodeAnalysis.Diagnostics;
6+
using System;
87
using System.Collections.Generic;
8+
using System.Globalization;
99
using System.Linq;
1010
using System.Text;
11+
using Microsoft.CodeAnalysis;
12+
using Microsoft.CodeAnalysis.Diagnostics;
1113
using Xunit;
1214

1315
namespace TestHelper
@@ -82,7 +84,7 @@ protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[]
8284
}
8385

8486
/// <summary>
85-
/// General method that gets a collection of actual diagnostics found in the source after the analyzer is run,
87+
/// General method that gets a collection of actual diagnostics found in the source after the analyzer is run,
8688
/// then verifies each of them.
8789
/// </summary>
8890
/// <param name="sources">An array of strings to create source documents from to run the analyzers on</param>
@@ -115,7 +117,7 @@ private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResult
115117
string diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : " NONE.";
116118

117119
Assert.True(false,
118-
string.Format("Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput));
120+
string.Format(CultureInfo.InvariantCulture, "Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput));
119121
}
120122

121123
for (int i = 0; i < expectedResults.Length; i++)
@@ -128,7 +130,7 @@ private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResult
128130
if (actual.Location != Location.None)
129131
{
130132
Assert.True(false,
131-
string.Format("Expected:\nA project diagnostic with No location\nActual:\n{0}",
133+
string.Format(CultureInfo.InvariantCulture, "Expected:\nA project diagnostic with No location\nActual:\n{0}",
132134
FormatDiagnostics(analyzer, actual)));
133135
}
134136
}
@@ -140,7 +142,9 @@ private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResult
140142
if (additionalLocations.Length != expected.Locations.Length - 1)
141143
{
142144
Assert.True(false,
143-
string.Format("Expected {0} additional locations but got {1} for Diagnostic:\r\n {2}\r\n",
145+
string.Format(
146+
CultureInfo.InvariantCulture,
147+
"Expected {0} additional locations but got {1} for Diagnostic:\r\n {2}\r\n",
144148
expected.Locations.Length - 1, additionalLocations.Length,
145149
FormatDiagnostics(analyzer, actual)));
146150
}
@@ -154,21 +158,27 @@ private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResult
154158
if (actual.Id != expected.Id)
155159
{
156160
Assert.True(false,
157-
string.Format("Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
161+
string.Format(
162+
CultureInfo.InvariantCulture,
163+
"Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
158164
expected.Id, actual.Id, FormatDiagnostics(analyzer, actual)));
159165
}
160166

161167
if (actual.Severity != expected.Severity)
162168
{
163169
Assert.True(false,
164-
string.Format("Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
170+
string.Format(
171+
CultureInfo.InvariantCulture,
172+
"Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
165173
expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual)));
166174
}
167175

168176
if (actual.GetMessage() != expected.Message)
169177
{
170178
Assert.True(false,
171-
string.Format("Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
179+
string.Format(
180+
CultureInfo.InvariantCulture,
181+
"Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
172182
expected.Message, actual.GetMessage(), FormatDiagnostics(analyzer, actual)));
173183
}
174184
}
@@ -186,7 +196,9 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno
186196
var actualSpan = actual.GetLineSpan();
187197

188198
Assert.True(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")),
189-
string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
199+
string.Format(
200+
CultureInfo.InvariantCulture,
201+
"Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
190202
expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic)));
191203

192204
var actualLinePosition = actualSpan.StartLinePosition;
@@ -197,7 +209,9 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno
197209
if (actualLinePosition.Line + 1 != expected.Line)
198210
{
199211
Assert.True(false,
200-
string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
212+
string.Format(
213+
CultureInfo.InvariantCulture,
214+
"Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
201215
expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic)));
202216
}
203217
}
@@ -208,7 +222,9 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno
208222
if (actualLinePosition.Character + 1 != expected.Column)
209223
{
210224
Assert.True(false,
211-
string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
225+
string.Format(
226+
CultureInfo.InvariantCulture,
227+
"Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
212228
expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic)));
213229
}
214230
}
@@ -239,17 +255,19 @@ private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diag
239255
var location = diagnostics[i].Location;
240256
if (location == Location.None)
241257
{
242-
builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
258+
builder.AppendFormat(CultureInfo.InvariantCulture, "GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
243259
}
244260
else
245261
{
246262
Assert.True(location.IsInSource,
247263
$"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");
248264

249-
string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt";
265+
string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs", StringComparison.Ordinal) ? "GetCSharpResultAt" : "GetBasicResultAt";
250266
var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;
251267

252-
builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
268+
builder.AppendFormat(
269+
CultureInfo.InvariantCulture,
270+
"{0}({1}, {2}, {3}.{4})",
253271
resultMethodName,
254272
linePosition.Line + 1,
255273
linePosition.Character + 1,

src/Components/Components/src/Routing/TemplateSegment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public TemplateSegment(string template, string segment, bool isParameter)
6161

6262
// Set the IsOptional flag to true if any type constraints
6363
// for this parameter are designated as optional.
64-
IsOptional = tokens.Skip(1).Any(token => token.EndsWith("?"));
64+
IsOptional = tokens.Skip(1).Any(token => token.EndsWith('?'));
6565

6666
Value = tokens[0];
6767
Constraints = tokens.Skip(1)

src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ public async Task CreateBinder_DateTime()
396396
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
397397

398398
// Act
399-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
399+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
400400

401401
Assert.Equal(expectedValue, value);
402402
Assert.Equal(1, component.Count);
@@ -415,7 +415,7 @@ public async Task CreateBinder_NullableDateTime()
415415
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
416416

417417
// Act
418-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
418+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
419419

420420
Assert.Equal(expectedValue, value);
421421
Assert.Equal(1, component.Count);
@@ -435,7 +435,7 @@ public async Task CreateBinder_DateTime_Format()
435435
var expectedValue = new DateTime(2018, 3, 4);
436436

437437
// Act
438-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
438+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
439439

440440
Assert.Equal(expectedValue, value);
441441
Assert.Equal(1, component.Count);
@@ -455,7 +455,7 @@ public async Task CreateBinder_NullableDateTime_Format()
455455
var expectedValue = new DateTime(2018, 3, 4);
456456

457457
// Act
458-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
458+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
459459

460460
Assert.Equal(expectedValue, value);
461461
Assert.Equal(1, component.Count);
@@ -474,7 +474,7 @@ public async Task CreateBinder_DateTimeOffset()
474474
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
475475

476476
// Act
477-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
477+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
478478

479479
Assert.Equal(expectedValue, value);
480480
Assert.Equal(1, component.Count);
@@ -493,7 +493,7 @@ public async Task CreateBinder_NullableDateTimeOffset()
493493
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
494494

495495
// Act
496-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
496+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
497497

498498
Assert.Equal(expectedValue, value);
499499
Assert.Equal(1, component.Count);
@@ -513,7 +513,7 @@ public async Task CreateBinder_DateTimeOffset_Format()
513513
var expectedValue = new DateTime(2018, 3, 4);
514514

515515
// Act
516-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
516+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
517517

518518
Assert.Equal(expectedValue, value);
519519
Assert.Equal(1, component.Count);
@@ -533,7 +533,7 @@ public async Task CreateBinder_NullableDateTimeOffset_Format()
533533
var expectedValue = new DateTime(2018, 3, 4);
534534

535535
// Act
536-
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
536+
await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
537537

538538
Assert.Equal(expectedValue, value);
539539
Assert.Equal(1, component.Count);

0 commit comments

Comments
 (0)