Skip to content

Commit 09edd79

Browse files
authored
CA1311 and CA1421 (#32634)
1 parent a3e1476 commit 09edd79

File tree

11 files changed

+205
-5
lines changed

11 files changed

+205
-5
lines changed

docs/core/extensions/performing-culture-insensitive-case-changes.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ Often, strings are converted to a standard case to enable easier lookup later. W
2525

2626
If a security decision is based on a case change operation, the operation should be culture-insensitive to ensure that the result is not affected by the value of `CultureInfo.CurrentCulture`. See the "String Comparisons that Use the Current Culture" section of the [Best Practices for Using Strings](../../standard/base-types/best-practices-strings.md) article for an example that demonstrates how culture-sensitive string operations can produce inconsistent results.
2727

28-
## Using the String.ToUpper and String.ToLower Methods
28+
## String.ToUpper and String.ToLower
2929

30-
For code clarity, it is recommended that you always use overloads of the `String.ToUpper` and `String.ToLower` methods that allow you to specify a `culture` parameter explicitly. For example, the following code performs an identifier lookup. The `key.ToLower` operation is culture-sensitive by default, but this behavior is not clear from reading the code.
30+
For code clarity, it's recommended that you always use overloads of the `String.ToUpper` and `String.ToLower` methods that let you specify a culture explicitly. For example, the following code performs an identifier lookup. The `key.ToLower` operation is culture-sensitive by default, but this behavior is not clear from reading the code.
3131

3232
### Example
3333

@@ -44,7 +44,7 @@ static object LookupKey(string key)
4444
}
4545
```
4646

47-
If you want the `key.ToLower` operation to be culture-insensitive, you should change the preceding example as follows to explicitly use the `CultureInfo.InvariantCulture` when changing the case.
47+
If you want the `key.ToLower` operation to be culture-insensitive, change the preceding example as follows to explicitly use `CultureInfo.InvariantCulture` when changing the case.
4848

4949
```vb
5050
Shared Function LookupKey(key As String) As Object
@@ -59,15 +59,16 @@ static object LookupKey(string key)
5959
}
6060
```
6161

62-
## Using the Char.ToUpper and Char.ToLower Methods
62+
## Char.ToUpper and Char.ToLower
6363

64-
Although the `Char.ToUpper` and `Char.ToLower` methods have the same characteristics as the `String.ToUpper` and `String.ToLower` methods, the only cultures that are affected are Turkish (Turkey) and Azerbaijani (Latin, Azerbaijan). These are the only two cultures with single-character casing differences. For more details about this unique case mapping, see the "Casing" section in the <xref:System.String> class topic. For code clarity and to ensure consistent results, it is recommended that you always use the overloads of these methods that allow you to explicitly specify a `culture` parameter.
64+
Although the `Char.ToUpper` and `Char.ToLower` methods have the same characteristics as the `String.ToUpper` and `String.ToLower` methods, the only cultures that are affected are Turkish (Turkey) and Azerbaijani (Latin, Azerbaijan). These are the only two cultures with single-character casing differences. For more details about this unique case mapping, see the "Casing" section in the <xref:System.String> class documentation. For code clarity and to ensure consistent results, it's recommended that you always use the overloads of these methods that accept a <xref:System.Globalization.CultureInfo> parameter.
6565

6666
## See also
6767

6868
- <xref:System.String.ToUpper%2A?displayProperty=nameWithType>
6969
- <xref:System.String.ToLower%2A?displayProperty=nameWithType>
7070
- <xref:System.Char.ToUpper%2A?displayProperty=nameWithType>
7171
- <xref:System.Char.ToLower%2A?displayProperty=nameWithType>
72+
- [CA1311: Specify a culture or use an invariant version](../../fundamentals/code-analysis/quality-rules/ca1311.md)
7273
- [Change case in .NET](../../standard/base-types/changing-case.md)
7374
- [Perform culture-insensitive string operations](performing-culture-insensitive-string-operations.md)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
title: "CA1311: Specify a culture or use an invariant version (code analysis)"
3+
description: "Learn about code analysis rule CA1311: Specify a culture or use an invariant version"
4+
ms.date: 11/16/2022
5+
ms.topic: reference
6+
f1_keywords:
7+
- CA1311
8+
- SpecifyCultureForToLowerAndToUpper
9+
helpviewer_keywords:
10+
- CA1311
11+
dev_langs:
12+
- CSharp
13+
- VB
14+
---
15+
# CA1311: Specify a culture or use an invariant version
16+
17+
| | Value |
18+
| ----------------------------------- | ------------------------------------------ |
19+
| **Rule ID** | CA1311 |
20+
| **Category** | [Globalization](globalization-warnings.md) |
21+
| **Fix is breaking or non-breaking** | Non-breaking |
22+
23+
## Cause
24+
25+
A call is made to <xref:System.String.ToUpper?displayProperty=nameWithType> or <xref:System.String.ToLower?displayProperty=nameWithType> without specifying a culture.
26+
27+
## Rule description
28+
29+
Specify a culture or use an invariant culture to avoid implicit dependency on the current culture when calling `ToUpper` or `ToLower`. Using an invariant culture yields consistent results regardless of the culture of an application.
30+
31+
## How to fix violations
32+
33+
Instead of calling the parameterless <xref:System.String.ToUpper?displayProperty=nameWithType> or <xref:System.String.ToLower?displayProperty=nameWithType> methods, call <xref:System.String.ToUpper(System.Globalization.CultureInfo)> or <xref:System.String.ToUpperInvariant>, or <xref:System.String.ToLower(System.Globalization.CultureInfo)> or <xref:System.String.ToLowerInvariant>.
34+
35+
## Example
36+
37+
The following code snippet shows a violation of rule CA1311:
38+
39+
```csharp
40+
string s = "hello";
41+
s = s.ToLower();
42+
```
43+
44+
```vb
45+
Dim s As String = "hello"
46+
s.ToLower()
47+
```
48+
49+
The following code snippet fixes the violation:
50+
51+
```csharp
52+
string s = "hello";
53+
s = s.ToLowerInvariant();
54+
```
55+
56+
```vb
57+
Dim s As String = "hello"
58+
s.ToLowerInvariant()
59+
```
60+
61+
## When to suppress warnings
62+
63+
It's safe to suppress a warning from this rule if you're certain that <xref:System.Threading.Thread.CurrentCulture%2A?displayProperty=nameWithType> will never change.
64+
65+
## Suppress a warning
66+
67+
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
68+
69+
```csharp
70+
#pragma warning disable CA1311
71+
// The code that's violating the rule is on this line.
72+
#pragma warning restore CA1311
73+
```
74+
75+
To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md).
76+
77+
```ini
78+
[*.{cs,vb}]
79+
dotnet_diagnostic.CA1311.severity = none
80+
```
81+
82+
To disable this entire category of rules, set the severity for the category to `none` in the [configuration file](../configuration-files.md).
83+
84+
```ini
85+
[*.{cs,vb}]
86+
dotnet_analyzer_diagnostic.category-Globalization.severity = none
87+
```
88+
89+
For more information, see [How to suppress code analysis warnings](../suppress-warnings.md).
90+
91+
## See also
92+
93+
- [Perform culture-insensitive case changes](../../../core/extensions/performing-culture-insensitive-case-changes.md)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
title: "CA1421: Method uses runtime marshalling when 'DisableRuntimeMarshallingAttribute' is applied"
3+
description: "Learn about code analysis rule CA1421: Method uses runtime marshalling when 'DisableRuntimeMarshallingAttribute' is applied"
4+
ms.date: 11/16/2022
5+
ms.topic: reference
6+
f1_keywords:
7+
- CA1421
8+
- MethodUsesRuntimeMarshallingEvenWhenMarshallingDisabled
9+
helpviewer_keywords:
10+
- CA1421
11+
dev_langs:
12+
- CSharp
13+
- VB
14+
---
15+
# CA1421: Method uses runtime marshalling when DisableRuntimeMarshallingAttribute is applied
16+
17+
| | Value |
18+
| ----------------------------------- | ------------------------------------------------ |
19+
| **Rule ID** | CA1421 |
20+
| **Category** | [Interoperability](interoperability-warnings.md) |
21+
| **Fix is breaking or non-breaking** | Non-breaking |
22+
23+
## Cause
24+
25+
A method uses runtime marshalling, and runtime marshalling is explicitly disabled.
26+
27+
## Rule description
28+
29+
If a method uses runtime marshalling when runtime marshalling is disabled, it can cause unexpected behavior differences at run time due to different expectations of a type's native layout.
30+
31+
## How to fix violations
32+
33+
Enable runtime marshalling or use features like `sizeof` and pointers to ensure accurate results.
34+
35+
## When to suppress warnings
36+
37+
Don't suppress a warning from this rule.
38+
39+
## Example
40+
41+
The following code snippet shows a violation of CA1421:
42+
43+
:::code language="csharp" source="snippets/csharp/extra-rules/ca1421.cs":::
44+
:::code language="vb" source="snippets/vb/extra-rules/ca1421.vb":::
45+
46+
To fix the violation, remove the <xref:System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute> attribute on the assembly.

docs/fundamentals/code-analysis/quality-rules/globalization-warnings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ Globalization rules support world-ready libraries and applications.
2828
|[CA1308: Normalize strings to uppercase](ca1308.md)|Strings should be normalized to uppercase. A small group of characters cannot make a round trip when they are converted to lowercase.|
2929
|[CA1309: Use ordinal StringComparison](ca1309.md)|A string comparison operation that is nonlinguistic does not set the StringComparison parameter to either Ordinal or OrdinalIgnoreCase. By explicitly setting the parameter to either StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase, your code often gains speed, becomes more correct, and becomes more reliable.|
3030
|[CA1310: Specify StringComparison for correctness](ca1310.md)|A string comparison operation uses a method overload that does not set a StringComparison parameter and uses culture-specific string comparison by default.|
31+
|[CA1311: Specify a culture or use an invariant version](ca1311.md)|Specify a culture or use an invariant culture to avoid implicit dependency on the current culture when calling `ToUpper` or `ToLower`.|
3132
|[CA2101: Specify marshalling for P/Invoke string arguments](ca2101.md)|A platform invoke member allows for partially trusted callers, has a string parameter, and does not explicitly marshal the string. This can cause a potential security vulnerability.|

docs/fundamentals/code-analysis/quality-rules/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,14 @@ The following table lists code quality analysis rules.
7474
> | [CA1308: Normalize strings to uppercase](ca1308.md) | Strings should be normalized to uppercase. A small group of characters cannot make a round trip when they are converted to lowercase. |
7575
> | [CA1309: Use ordinal StringComparison](ca1309.md) | A string comparison operation that is nonlinguistic does not set the StringComparison parameter to either Ordinal or OrdinalIgnoreCase. By explicitly setting the parameter to either StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase, your code often gains speed, becomes more correct, and becomes more reliable. |
7676
> | [CA1310: Specify StringComparison for correctness](ca1310.md) | A string comparison operation uses a method overload that does not set a StringComparison parameter and uses culture-specific string comparison by default. |
77+
> | [CA1311: Specify a culture or use an invariant version](ca1311.md) | Specify a culture or use an invariant culture to avoid implicit dependency on the current culture when calling `ToUpper` or `ToLower`. |
7778
> | [CA1401: P/Invokes should not be visible](ca1401.md) | A public or protected method in a public type has the System.Runtime.InteropServices.DllImportAttribute attribute (also implemented by the Declare keyword in Visual Basic). Such methods should not be exposed. |
7879
> | [CA1416: Validate platform compatibility](ca1416.md) | Using platform-dependent APIs on a component makes the code no longer work across all platforms. |
7980
> | [CA1417: Do not use `OutAttribute` on string parameters for P/Invokes](ca1417.md) | String parameters passed by value with the `OutAttribute` can destabilize the runtime if the string is an interned string. |
8081
> | [CA1418: Use valid platform string](ca1418.md) | Platform compatibility analyzer requires a valid platform name and version. |
8182
> | [CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle'](ca1419.md) | Providing a parameterless constructor that is as visible as the containing type for a type derived from `System.Runtime.InteropServices.SafeHandle` enables better performance and usage with source-generated interop solutions. |
8283
> | [CA1420: Property, type, or attribute requires runtime marshalling](ca1420.md) | Using features that require runtime marshalling when runtime marshalling is disabled will result in run-time exceptions. |
84+
> | [CA1421: Method uses runtime marshalling when DisableRuntimeMarshallingAttribute is applied](ca1421.md) | A method uses runtime marshalling, and runtime marshalling is explicitly disabled. |
8385
> | [CA1422: Validate platform compatibility](ca1422.md) | Calling an API that's obsolete in a given OS (version) from a call site that's reachable from that OS (version) is not recommended. |
8486
> | [CA1501: Avoid excessive inheritance](ca1501.md) | A type is more than four levels deep in its inheritance hierarchy. Deeply nested type hierarchies can be difficult to follow, understand, and maintain. |
8587
> | [CA1502: Avoid excessive complexity](ca1502.md) | This rule measures the number of linearly independent paths through the method, which is determined by the number and complexity of conditional branches. |

docs/fundamentals/code-analysis/quality-rules/interoperability-warnings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ Portability rules support portability across different platforms. Interoperabili
2929
| [CA1418: Use valid platform string](ca1418.md) | Platform compatibility analyzer requires a valid platform name and version. |
3030
| [CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle'](ca1419.md) | Providing a parameterless constructor that is as visible as the containing type for a type derived from `System.Runtime.InteropServices.SafeHandle` enables better performance and usage with source-generated interop solutions. |
3131
| [CA1420: Property, type, or attribute requires runtime marshalling](ca1420.md) | Using features that require runtime marshalling when runtime marshalling is disabled will result in run-time exceptions. |
32+
| [CA1421: Method uses runtime marshalling when DisableRuntimeMarshallingAttribute is applied](ca1421.md) | A method uses runtime marshalling, and runtime marshalling is explicitly disabled. |
3233
| [CA1422: Validate platform compatibility](ca1422.md) | Calling an API that's obsolete in a given OS (version) from a call site that's reachable from that OS (version) is not recommended. |
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Runtime.CompilerServices;
2+
using System.Runtime.InteropServices;
3+
4+
[assembly: DisableRuntimeMarshalling]
5+
6+
class C
7+
{
8+
public void Test()
9+
{
10+
nint offset = Marshal.OffsetOf(typeof(ValueType), "field");
11+
}
12+
}
13+
14+
struct ValueType
15+
{
16+
int field;
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Library</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<RootNamespace>extra_rules</RootNamespace>
7+
</PropertyGroup>
8+
9+
</Project>
10+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
Imports System.Runtime.CompilerServices
3+
Imports System.Runtime.InteropServices
4+
5+
<Assembly: DisableRuntimeMarshalling>
6+
7+
Class C
8+
Shared Sub S1()
9+
Dim offset As IntPtr = Marshal.OffsetOf(GetType(ValueType), "field")
10+
End Sub
11+
End Class
12+
13+
Structure ValueType
14+
Dim field As Integer
15+
End Structure
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Library</OutputType>
5+
<RootNamespace>extra_rules</RootNamespace>
6+
<TargetFramework>net7.0</TargetFramework>
7+
</PropertyGroup>
8+
9+
</Project>
10+

0 commit comments

Comments
 (0)