Skip to content

Commit

Permalink
Runtime90357 6012 (#6885)
Browse files Browse the repository at this point in the history
* Fix IndexOfOfRangeException for non-formatting methods.

* Check format specification on non-format methods

* Use different diagnostic message if format is malformed.

* Fix bug where rule was not taking actual index values into account

* Running 'msbuild /t:pack'
  • Loading branch information
manfred-brands authored Aug 25, 2023
1 parent 4efa61a commit 972fa0a
Show file tree
Hide file tree
Showing 17 changed files with 187 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@
<data name="ProvideCorrectArgumentsToFormattingMethodsMessage" xml:space="preserve">
<value>Provide correct arguments to formatting methods</value>
</data>
<data name="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage" xml:space="preserve">
<value>The format argument is not a valid format string</value>
</data>
<data name="TestForNaNCorrectlyTitle" xml:space="preserve">
<value>Test for NaN correctly</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Analyzer.Utilities;
using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis;
Expand All @@ -23,7 +24,7 @@ public class ProvideCorrectArgumentsToFormattingMethodsAnalyzer : DiagnosticAnal
{
internal const string RuleId = "CA2241";

internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
internal static readonly DiagnosticDescriptor ArgumentCountRule = DiagnosticDescriptorHelper.Create(
RuleId,
CreateLocalizableResourceString(nameof(ProvideCorrectArgumentsToFormattingMethodsTitle)),
CreateLocalizableResourceString(nameof(ProvideCorrectArgumentsToFormattingMethodsMessage)),
Expand All @@ -33,7 +34,18 @@ public class ProvideCorrectArgumentsToFormattingMethodsAnalyzer : DiagnosticAnal
isPortedFxCopRule: true,
isDataflowRule: false);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
internal static readonly DiagnosticDescriptor InvalidFormatRule = DiagnosticDescriptorHelper.Create(
RuleId,
CreateLocalizableResourceString(nameof(ProvideCorrectArgumentsToFormattingMethodsTitle)),
CreateLocalizableResourceString(nameof(ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage)),
DiagnosticCategory.Usage,
RuleLevel.BuildWarningCandidate,
description: CreateLocalizableResourceString(nameof(ProvideCorrectArgumentsToFormattingMethodsDescription)),
isPortedFxCopRule: true,
isDataflowRule: false);

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

public override void Initialize(AnalysisContext context)
{
Expand Down Expand Up @@ -65,6 +77,13 @@ public override void Initialize(AnalysisContext context)
int expectedStringFormatArgumentCount = GetFormattingArguments(stringFormat);
if (expectedStringFormatArgumentCount < 0)
{
// Malformed format specification
operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(InvalidFormatRule));
return;
}
// explicit parameter case
if (info.ExpectedStringFormatArgumentCount >= 0)
{
Expand All @@ -77,11 +96,16 @@ public override void Initialize(AnalysisContext context)
if (info.ExpectedStringFormatArgumentCount != expectedStringFormatArgumentCount)
{
operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(Rule));
operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(ArgumentCountRule));
}
return;
}
else if (info.ExpectedStringFormatArgumentCount == -2)
{
// Not a formatting method, we only checked the format specification.
return;
}
// ensure argument is an array
IArgumentOperation paramsArgument = invocation.Arguments[info.FormatStringIndex + 1];
Expand Down Expand Up @@ -111,7 +135,7 @@ public override void Initialize(AnalysisContext context)
int actualArgumentCount = initializer.ElementValues.Length;
if (actualArgumentCount != expectedStringFormatArgumentCount)
{
operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(Rule));
operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(ArgumentCountRule));
}
}, OperationKind.Invocation);
});
Expand Down Expand Up @@ -308,7 +332,7 @@ private static int GetFormattingArguments(string format)

} // end of main loop

return uniqueNumbers.Count;
return uniqueNumbers.Count == 0 ? 0 : uniqueNumbers.Max() + 1;
}

private class StringFormatInfo
Expand Down Expand Up @@ -352,7 +376,7 @@ public StringFormatInfo(Compilation compilation)
}

// Check if this the underlying method is user configured string formatting method.
var additionalStringFormatMethodsOption = context.Options.GetAdditionalStringFormattingMethodsOption(Rule, context.Operation.Syntax.SyntaxTree, context.Compilation);
var additionalStringFormatMethodsOption = context.Options.GetAdditionalStringFormattingMethodsOption(ArgumentCountRule, context.Operation.Syntax.SyntaxTree, context.Compilation);
if (additionalStringFormatMethodsOption.Contains(method.OriginalDefinition) &&
TryGetFormatInfoByParameterName(method, out info))
{
Expand All @@ -362,7 +386,7 @@ public StringFormatInfo(Compilation compilation)
// Check if the user configured automatic determination of formatting methods.
// If so, check if the method called has a 'string format' parameter followed by an params array.
var determineAdditionalStringFormattingMethodsAutomatically = context.Options.GetBoolOptionValue(EditorConfigOptionNames.TryDetermineAdditionalStringFormattingMethodsAutomatically,
Rule, context.Operation.Syntax.SyntaxTree, context.Compilation, defaultValue: false);
ArgumentCountRule, context.Operation.Syntax.SyntaxTree, context.Compilation, defaultValue: false);
if (determineAdditionalStringFormattingMethodsAutomatically &&
TryGetFormatInfoByParameterName(method, out info) &&
info.ExpectedStringFormatArgumentCount == -1)
Expand Down Expand Up @@ -424,6 +448,13 @@ private bool TryGetFormatInfo(IMethodSymbol method, int formatIndex, [NotNullWhe

private static int GetExpectedNumberOfArguments(ImmutableArray<IParameterSymbol> parameters, int formatIndex)
{
if (formatIndex == parameters.Length - 1)
{
// format specification is the last parameter (e.g. CompositeFormat.Parse)
// this is therefore not a formatting method.
return -2;
}

// check params
IParameterSymbol nextParameter = parameters[formatIndex + 1];
if (nextParameter.IsParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Obecné přetypování (IL unbox.any) používané sekvencí vrácenou metodou E
<target state="translated">Argument formátu, který se předává do System.String.Format, neobsahuje položku formátování, která odpovídá jednotlivým argumentům objektů, nebo naopak.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Poskytněte metodám formátování správné argumenty</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type
<target state="translated">Das an "System.String.Format" übergebene Formatargument enthält kein Formatelement, das den einzelnen Objektargumenten entspricht bzw. umgekehrt.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Geeignete Argumente für Formatierungsmethoden angeben</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip
<target state="translated">El argumento de cadena format pasado a System.String.Format no contiene un elemento de formato que corresponda a cada argumento de objeto o viceversa.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Proporcionar argumentos correctos para los métodos de formato</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en
<target state="translated">L'argument de mise en forme passé à System.String.Format ne contient aucun élément de mise en forme pour chaque argument d'objet correspondant, ou vice versa.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Indiquer le nombre correct d'arguments dans les méthodes de mise en forme</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi
<target state="translated">L'argomento format passato a System.String.Format non contiene un elemento di formato corrispondente a ogni argomento dell'oggetto o viceversa.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Fornire gli argomenti corretti ai metodi di formattazione</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Enumerable.OfType&lt;T&gt; で使用されるジェネリック型チェック (
<target state="translated">System.String.Format に渡される書式引数には、各オブジェクト引数に対応する書式項目が含まれていないか、各書式項目に対応するオブジェクト引数が含まれていません。</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">書式設定メソッドに正しい引数を指定します</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Enumerable.OfType&lt;T&gt;에서 사용하는 제네릭 형식 검사(C# 'is'
<target state="translated">System.String.Format으로 전달된 format 인수에 각 개체 인수에 해당하는 format 항목이 포함되지 않으며 그 반대의 경우도 마찬가지입니다.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">서식 지정 메서드에 올바른 인수를 제공하세요.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr
<target state="translated">Argument formatu przekazywany do metody System.String.Format nie zawiera elementu formatu odpowiadającego każdemu argumentowi obiektu lub odwrotnie.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Określ poprawne argumenty dla metod formatujących</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Ampliação e conversões definidas pelo usuário não são compatíveis com tip
<target state="translated">O argumento de formato passado para System.String.Format não contém um item de formato correspondente a cada argumento de objeto ou vice-versa.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Fornecer os argumentos corretos para métodos de formatação</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Widening and user defined conversions are not supported with generic types.</sou
<target state="translated">Передаваемый в System.String.Format аргумент формата не содержит элемент формата, соответствующий каждому из аргументов объекта, или наоборот.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Задайте правильные аргументы для методов форматирования</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen
<target state="translated">System.String.Format’a geçirilen biçim bağımsız değişkeni, her nesne bağımsız değişkenine karşılık gelen bir biçim öğesi içermiyor ve tersi için de aynısı geçerli.</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">Biçimlendirme yöntemlerine doğru bağımsız değişkenleri sağlayın</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Enumerable.OfType&lt;T&gt; 使用的泛型类型检查 (C# 'is' operator/IL 'isi
<target state="translated">传递到 System.String.Format 的 format 参数不包含与各对象参数相对应的格式项,反之亦然。</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">为格式化方法提供正确的参数</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ Enumerable.OfType&lt;T&gt; 使用的一般型別檢查 (C# 'is' operator/IL 'isi
<target state="translated">傳遞給 System.String.Format 的格式化引數,並未包含與每個物件引數相對應的格式項目,反之亦然。</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsInvalidFormatMessage">
<source>The format argument is not a valid format string</source>
<target state="new">The format argument is not a valid format string</target>
<note />
</trans-unit>
<trans-unit id="ProvideCorrectArgumentsToFormattingMethodsMessage">
<source>Provide correct arguments to formatting methods</source>
<target state="translated">為格式化方法提供正確的引數</target>
Expand Down
1 change: 0 additions & 1 deletion src/NetAnalyzers/RulesMissingDocumentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ CA1863 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-
CA1865 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865> | Use char overload |
CA1866 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1866> | Use char overload |
CA1867 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1867> | Use char overload |
CA1869 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869> | Cache and reuse 'JsonSerializerOptions' instances |
CA2021 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021> | Do not call Enumerable.Cast\<T> or Enumerable.OfType\<T> with incompatible types |
CA2261 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2261> | Do not use ConfigureAwaitOptions.SuppressThrowing with Task\<TResult> |
Loading

0 comments on commit 972fa0a

Please sign in to comment.