Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement DoNotIgnoreAttribute analyzer for method return values #6546

Closed
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
453daee
Implement DoNotIgnoreAttribute analyzer for method return values
jeffhandley Mar 25, 2023
293847b
Add VB test coverage
jeffhandley Mar 25, 2023
5c9f8c0
Add support for the attribute's Message property
jeffhandley Mar 25, 2023
12b4188
Make placeholder attributes internal to the tests
jeffhandley Mar 25, 2023
f0aeed3
Add artifacts for new analyzer
jeffhandley Mar 26, 2023
2c77260
Update placeholder attribute to only target return values
jeffhandley Mar 26, 2023
0cb66fd
Update missing docs file via 'dotnet msbuild /t:pack'
jeffhandley Mar 26, 2023
2a37b7d
Set default severity of CA2022 to Warning
jeffhandley Mar 27, 2023
bd1d965
Add more test cases for consuming the return value
jeffhandley Mar 27, 2023
46a116e
Apply feedback. Add tests for custom attributes in different forms.
jeffhandley Apr 1, 2023
7cc059d
Recognize and flag ignored async method results
jeffhandley Apr 1, 2023
2b694f3
Merge branch 'main' into jeffhandley/donotignoreattribute
jeffhandley Apr 1, 2023
816f013
Update diagnostic description
jeffhandley Apr 1, 2023
b6c2391
Recognize ValueTask<T> and all Task-like types
jeffhandley Apr 1, 2023
6817783
Run dotnet msbuild /t:pack
jeffhandley Apr 1, 2023
d81c28f
Check the IAwaitOperation type instead of interrogating the method re…
jeffhandley Apr 2, 2023
d81d39d
Cannot prevent diagnostic for [DoNotIgnore] awaited void in VB. Incre…
jeffhandley Apr 4, 2023
98ef5a8
Rename async/await tests. Some are async. Some are await. Some are both.
jeffhandley Apr 4, 2023
cd1dcac
Get non-async/await VB tests up to parity with C# tests
jeffhandley Apr 4, 2023
7906016
Remove unnecessary Using statment
jeffhandley Apr 4, 2023
58659d0
dotnet msbuild /t:Pack
jeffhandley Apr 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CA1858 | Performance | Info | UseStartsWithInsteadOfIndexOfComparisonWithZero, [
CA1859 | Performance | Info | UseConcreteTypeAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)
CA1860 | Performance | Info | PreferLengthCountIsEmptyOverAnyAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860)
CA2021 | Reliability | Warning | DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021)
CA2022 | Reliability | Warning | DoNotIgnoreReturnValueAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2022)

### Removed Rules

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2040,4 +2040,16 @@ Widening and user defined conversions are not supported with generic types.</val
<data name="PreferIsEmptyOverAnyMessage" xml:space="preserve">
<value>Prefer an 'IsEmpty' check rather than using 'Any()', both for clarity and for performance</value>
</data>
<data name="DoNotIgnoreReturnValueMessage" xml:space="preserve">
<value>Do not ignore the return value of '{0}'</value>
</data>
<data name="DoNotIgnoreReturnValueDescription" xml:space="preserve">
<value>The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</value>
</data>
<data name="DoNotIgnoreReturnValueTitle" xml:space="preserve">
<value>Do not ignore return value</value>
</data>
<data name="DoNotIgnoreReturnValueMessageCustom" xml:space="preserve">
<value>Do not ignore the return value of '{0}': {1}</value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

using System.Collections.Immutable;
using Analyzer.Utilities;
using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;

namespace Microsoft.NetCore.Analyzers.Runtime
{
using static MicrosoftNetCoreAnalyzersResources;

[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public sealed class DoNotIgnoreReturnValueAnalyzer : DiagnosticAnalyzer
{
internal const string CA2022RuleId = "CA2022";

internal static readonly DiagnosticDescriptor DoNotIgnoreReturnValueRule = DiagnosticDescriptorHelper.Create(
CA2022RuleId,
CreateLocalizableResourceString(nameof(DoNotIgnoreReturnValueTitle)),
CreateLocalizableResourceString(nameof(DoNotIgnoreReturnValueMessage)),
DiagnosticCategory.Reliability,
RuleLevel.BuildWarning,
CreateLocalizableResourceString(nameof(DoNotIgnoreReturnValueDescription)),
isPortedFxCopRule: false,
isDataflowRule: false);

internal static readonly DiagnosticDescriptor DoNotIgnoreReturnValueRuleWithMessage = DiagnosticDescriptorHelper.Create(
CA2022RuleId,
CreateLocalizableResourceString(nameof(DoNotIgnoreReturnValueTitle)),
CreateLocalizableResourceString(nameof(DoNotIgnoreReturnValueMessageCustom)),
DiagnosticCategory.Reliability,
RuleLevel.BuildWarning,
CreateLocalizableResourceString(nameof(DoNotIgnoreReturnValueDescription)),
isPortedFxCopRule: false,
isDataflowRule: false);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(DoNotIgnoreReturnValueRule);

public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

context.RegisterOperationBlockStartAction(context =>
{
if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDiagnosticsCodeAnalysisDoNotIgnoreAttribute, out var doNotIgnoreAttribute))
{
return;
}

context.RegisterOperationAction(context =>
{
var invocation = (IInvocationOperation)context.Operation;

if (!invocation.TargetMethod.ReturnsVoid && invocation.Parent.Kind == OperationKind.ExpressionStatement)
{
var attributeApplied = invocation.TargetMethod.GetReturnTypeAttributes().WhereAsArray(a => a.AttributeClass == doNotIgnoreAttribute);

if (!attributeApplied.IsEmpty)
{
var message = attributeApplied[0].NamedArguments.WhereAsArray(arg => arg.Key == "Message");
var messageStr = message.IsEmpty ? null : (string)message[0].Value.Value;

if (!string.IsNullOrEmpty(messageStr))
{
context.ReportDiagnostic(invocation.CreateDiagnostic(DoNotIgnoreReturnValueRuleWithMessage, invocation.TargetMethod.FormatMemberName(), messageStr!));
}
else
{
context.ReportDiagnostic(invocation.CreateDiagnostic(DoNotIgnoreReturnValueRule, invocation.TargetMethod.FormatMemberName()));
}
}
}
}, OperationKind.Invocation);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,26 @@ Widening and user defined conversions are not supported with generic types.</tar
<target state="translated">Našlo se potenciální ohrožení zabezpečení, kde {0} v metodě {1} je možné poškodit pevně zakódovaným klíčem z {2} v metodě {3}.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueDescription">
<source>The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</source>
<target state="new">The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessage">
<source>Do not ignore the return value of '{0}'</source>
<target state="new">Do not ignore the return value of '{0}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessageCustom">
<source>Do not ignore the return value of '{0}': {1}</source>
<target state="new">Do not ignore the return value of '{0}': {1}</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueTitle">
<source>Do not ignore return value</source>
<target state="new">Do not ignore return value</target>
<note />
</trans-unit>
<trans-unit id="DoNotInstallRootCertDescription">
<source>By default, the Trusted Root Certification Authorities certificate store is configured with a set of public CAs that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root CAs can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack - and a single vulnerable, malicious or coercible CA undermines the security of the entire system. To make matters worse, these attacks can go unnoticed quite easily.</source>
<target state="translated">Standardně je úložiště certifikátů důvěryhodných kořenových certifikačních autorit nakonfigurované na sadu veřejných CA, které splnily požadavky programu Microsoft Root Certificate Program. Vzhledem k tomu, že všechny důvěryhodné kořenové CA můžou vystavovat certifikáty pro libovolnou doménu, útočník si může vybrat slabou nebo zranitelnou CA, kterou si sami nainstalujete na cíl útoku – a jedna ohrožená, škodlivá nebo zranitelná CA ohrožuje zabezpečení celého systému. A co je horší, tyto útoky se dají vcelku snadno skrýt.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,26 @@ Widening and user defined conversions are not supported with generic types.</tar
<target state="translated">Es wurde ein potenzielles Sicherheitsrisiko ermittelt. "{0}" in der Methode "{1}" wurde möglicherweise durch einen hartcodierten Schlüssel aus "{2}" in Methode "{3}" verfälscht.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueDescription">
<source>The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</source>
<target state="new">The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessage">
<source>Do not ignore the return value of '{0}'</source>
<target state="new">Do not ignore the return value of '{0}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessageCustom">
<source>Do not ignore the return value of '{0}': {1}</source>
<target state="new">Do not ignore the return value of '{0}': {1}</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueTitle">
<source>Do not ignore return value</source>
<target state="new">Do not ignore return value</target>
<note />
</trans-unit>
<trans-unit id="DoNotInstallRootCertDescription">
<source>By default, the Trusted Root Certification Authorities certificate store is configured with a set of public CAs that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root CAs can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack - and a single vulnerable, malicious or coercible CA undermines the security of the entire system. To make matters worse, these attacks can go unnoticed quite easily.</source>
<target state="translated">Standardmäßig ist der Zertifikatspeicher der vertrauenswürdigen Stammzertifizierungsstellen mit einem Satz öffentlicher Zertifizierungsstellen konfiguriert, die die Anforderungen des Microsoft-Programms für Stammzertifikate erfüllen. Da alle vertrauenswürdigen Stammzertifizierungsstellen Zertifikate für eine beliebige Domäne ausstellen können, kann ein Angreifer eine schwache oder zwingende Zertifizierungsstelle, die Sie selbst installieren, als Ziel für einen Angriff auswählen. Auf diese Weise kann eine einzelne unsichere, schädliche oder zwingende Zertifizierungsstelle die Sicherheit des gesamten Systems untergraben. Hinzu kommt, dass diese Angriffe leicht unbemerkt bleiben können.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,26 @@ Widening and user defined conversions are not supported with generic types.</tar
<target state="translated">Se encontró una posible vulnerabilidad de seguridad por la que podría contaminarse "{0}" en el método "{1}" con una clave codificada de forma rígida de "{2}" en el método "{3}".</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueDescription">
<source>The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</source>
<target state="new">The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessage">
<source>Do not ignore the return value of '{0}'</source>
<target state="new">Do not ignore the return value of '{0}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessageCustom">
<source>Do not ignore the return value of '{0}': {1}</source>
<target state="new">Do not ignore the return value of '{0}': {1}</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueTitle">
<source>Do not ignore return value</source>
<target state="new">Do not ignore return value</target>
<note />
</trans-unit>
<trans-unit id="DoNotInstallRootCertDescription">
<source>By default, the Trusted Root Certification Authorities certificate store is configured with a set of public CAs that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root CAs can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack - and a single vulnerable, malicious or coercible CA undermines the security of the entire system. To make matters worse, these attacks can go unnoticed quite easily.</source>
<target state="translated">De forma predeterminada, el almacén de certificados de entidades de certificación raíz de confianza está configurado con un conjunto de entidades de certificación públicas que cumplen los requisitos del programa de certificados raíz de Microsoft. Dado que todas las entidades de certificación raíz de confianza pueden emitir certificados para cualquier dominio, un atacante puede elegir una entidad de certificación coaccionable o débil que instale por su cuenta para destinar un ataque, y una única entidad de certificación vulnerable, malintencionada o convertible socava la seguridad de todo el sistema. Para empeorar las cosas, estos ataques pueden pasar desapercibidos con bastante facilidad.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,26 @@ Widening and user defined conversions are not supported with generic types.</tar
<target state="translated">Une vulnérabilité potentielle liée à la sécurité a été détectée. '{0}' dans la méthode '{1}' peut être souillé par une clé codée en dur en provenance de '{2}' dans la méthode '{3}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueDescription">
<source>The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</source>
<target state="new">The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessage">
<source>Do not ignore the return value of '{0}'</source>
<target state="new">Do not ignore the return value of '{0}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessageCustom">
<source>Do not ignore the return value of '{0}': {1}</source>
<target state="new">Do not ignore the return value of '{0}': {1}</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueTitle">
<source>Do not ignore return value</source>
<target state="new">Do not ignore return value</target>
<note />
</trans-unit>
<trans-unit id="DoNotInstallRootCertDescription">
<source>By default, the Trusted Root Certification Authorities certificate store is configured with a set of public CAs that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root CAs can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack - and a single vulnerable, malicious or coercible CA undermines the security of the entire system. To make matters worse, these attacks can go unnoticed quite easily.</source>
<target state="translated">Par défaut, le magasin de certificats Autorités de certification racines de confiance est configuré avec un ensemble d'autorités de certification publiques qui répond aux exigences du programme de certificat racine Microsoft. Comme toutes les autorités de certification racines de confiance peuvent émettre des certificats pour n'importe quel domaine, un attaquant peut choisir une autorité de certification faible ou coercible que vous installez par vous-même, or une seule autorité de certification vulnérable, malveillante ou coercible compromet la sécurité de l'ensemble du système. Pour compliquer la situation, ces attaques passent facilement inaperçues.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,26 @@ Widening and user defined conversions are not supported with generic types.</tar
<target state="translated">È stata trovata una potenziale vulnerabilità di sicurezza in cui '{0}' nel metodo '{1}' può essere contaminato dalla chiave hardcoded di '{2}' nel metodo '{3}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueDescription">
<source>The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</source>
<target state="new">The return value from '{0}' is being ignored, but the method is annotated to indicate its return value should not be ignored.</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessage">
<source>Do not ignore the return value of '{0}'</source>
<target state="new">Do not ignore the return value of '{0}'</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueMessageCustom">
<source>Do not ignore the return value of '{0}': {1}</source>
<target state="new">Do not ignore the return value of '{0}': {1}</target>
<note />
</trans-unit>
<trans-unit id="DoNotIgnoreReturnValueTitle">
<source>Do not ignore return value</source>
<target state="new">Do not ignore return value</target>
<note />
</trans-unit>
<trans-unit id="DoNotInstallRootCertDescription">
<source>By default, the Trusted Root Certification Authorities certificate store is configured with a set of public CAs that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root CAs can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack - and a single vulnerable, malicious or coercible CA undermines the security of the entire system. To make matters worse, these attacks can go unnoticed quite easily.</source>
<target state="translated">Per impostazione predefinita, l'archivio certificati di Autorità di certificazione radice disponibile nell'elenco locale è configurato con un set di CA pubbliche che soddisfa i requisiti del programma Microsoft Root Certificate. Dal momento che tutte le CA radice attendibili possono rilasciare certificati per qualsiasi dominio, un utente malintenzionato può selezionare come destinazione di attacco una CA debole o coercibile installata dall'utente. Una CA vulnerabile, dannosa o coercibile compromette la sicurezza dell'intero sistema, senza contare che questi attacchi possono passare inosservati abbastanza facilmente.</target>
Expand Down
Loading