Saudações a todos os amantes de insetos. O ano novo está chegando, então é hora de fazer um balanço do ano que está saindo. Por tradição, uma classificação dos erros mais interessantes descobertos pela equipe do PVS-Studio em projetos C # abertos para 2019. Você está pronta? Então vamos começar.
Décimo lugar: “Confunda todo mundo”
V3066 Possível ordem incorreta de argumentos passada para o método 'AdjustCellBorderStyle': 'isFirstDisplayedRow' e 'isFirstDisplayedColumn'. DataGridViewComboBoxCell.cs 1934
protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) { .... dgvabsEffective = AdjustCellBorderStyle( DataGridView.AdvancedCellBorderStyle, dgvabsPlaceholder, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedRow,
Erro do artigo "
WinForms: erros, Holmes ". O analisador indica que, ao passar argumentos para o método, os dois últimos argumentos foram revertidos. Dê uma olhada na
declaração AdjustCellBorderStyle :
public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle( DataGridViewAdvancedBorderStyledataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { .... }
Parece que o analisador está certo. Freqüentemente, alguns argumentos são deliberadamente passados na ordem inversa, por exemplo, para trocar algumas variáveis. Mas não parece que esse seja exatamente o caso. Primeiro, as variáveis do tipo
bool são confusas. Em segundo lugar, os nomes dos métodos também são comuns: sem “Swap” ou “Reverse”. Além disso, não é tão difícil cometer um erro como este: as pessoas geralmente percebem a ordem do par de linhas / colunas de maneira diferente.
Nono lugar: "O Infinito está próximo"
V3110 Possível recursão infinita dentro do método 'TryValidateModel'. PrefixedModuleUpdater.cs 48
public bool TryValidateModel(object model, string prefix) { return TryValidateModel(model, Prefix(prefix)); }
Erro do artigo "
Pesquisando e analisando erros no código do Orchard CMS ". Foi cometido um erro que causa uma recursão infinita. Para entender como esse erro pode ter sido cometido, é necessário observar a sobrecarga do método
TryValidateModel :
public bool TryValidateModel(object model) { return _updateModel.TryValidateModel(model); }
É provável que, no primeiro caso, uma chamada do formulário seja usada:
public bool TryValidateModel(object model, string prefix) { return _updateModel.TryValidateModel(model, Prefix(prefix)); }
O código compilado porque
_updateModel é do tipo
IUpdateModel e a classe atual também implementa a interface
IUpdateModel .
Oitavo lugar: "Tente, encontre"
V3091 Análise empírica. É possível que um erro de digitação esteja presente dentro da string literal: "ID do grupo de gerenciamento". A palavra 'Id' é suspeita. Constants.cs 36
public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id";
O erro ocorreu no artigo “
Azure PowerShell:“ basicamente inofensivo ”. difícil de detectar.
Sétimo lugar: "Apenas esquecido"
V3078 A ordem de classificação original será perdida após a chamada repetitiva ao método 'OrderBy'. Use o método 'ThenBy' para preservar a classificação original. GridModel.Selection.cs 107
internal partial class GridModel { private void BuildCellSelectionRegions(....) { .... this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .OrderBy(c => c.RowItemInfo.LayoutInfo.Line)); } }
Erro do artigo "
Verificando a interface do usuário da Telerik para UWP para se familiarizar com o PVS-Studio ". Devido à reutilização de
OrderBy para uma coleção já classificada, o resultado da classificação anterior será perdido. Você deve usar o
ThenBy :
this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .ThenBy(c => c.RowItemInfo.LayoutInfo.Line));
Tais erros são cometidos por descuido ou ignorância. Eu acho que copiar e colar é o culpado.
Sexto lugar: "O código está documentado", disseram eles
V3009 É estranho que esse método sempre retorne um e o mesmo valor de 'true'. MaskedTextProvider.cs 1529
public bool Remove(out int testPosition, out MaskedTextResultHint resultHint) { .... if (lastAssignedPos == INVALID_INDEX) { .... return true;
Erro do artigo "
Verificando o código-fonte das bibliotecas do .NET Core com o analisador estático PVS-Studio ". O método sempre retornará
verdadeiro . Sim, isso é um erro, mas outra coisa é curiosa. Um comentário detalhado é anexado ao método:
Remove o último caractere da sequência formatada. (Remova o último caractere na cadeia virtual). Na saída, o parâmetro out contém a posição em que a operação foi realmente executada. Esta posição é relativa à cadeia de teste. O parâmetro MaskedTextResultHint out fornece mais informações sobre o resultado da operação. Retorna verdadeiro com sucesso, caso contrário , falso .Concentre-se na última frase. Mas quem nunca lê esses comentários? Mas, falando sério, esse erro ocorre facilmente, por exemplo, ao refatorar ou depurar. Queríamos checar a opção quando o resultado do método sempre for
verdadeiro ; esquecemos de devolver tudo como estava antes.
Quinto lugar: "Me indexe imediatamente!"
V3102 Acesso suspeito ao elemento do objeto 'seq' por um índice constante dentro de um loop. XmlQueryRuntime.cs 738
public bool MatchesXmlType(IList<XPathItem> seq, ....) { .... for (int i = 0; i < seq.Count; i++) { if (!CreateXmlType(seq[0]).IsSubtypeOf(....)) return false; } return true; }
Erro do artigo "
Verificando o código-fonte das bibliotecas do .NET Core com o analisador estático PVS-Studio ". Ao percorrer a coleção
seq , o loop
for usa
por engano acesso apenas ao seu primeiro elemento em todas as iterações (índice 0 em vez de
i ).
Quarto lugar: "Apenas um dólar e não o suficiente"
V3138 O literal de
sequência contém potencial expressão interpolada. Considere inspecionar: e. SSPIHandleCache.cs 42
internal static void CacheCredential(SafeFreeCredentials newHandle) { try { .... } catch (Exception e) { if (!ExceptionCheck.IsFatal(e)) { NetEventSource.Fail(null, "Attempted to throw: {e}"); } } }
Erro do artigo "
Verificando o código-fonte das bibliotecas do .NET Core com o analisador estático PVS-Studio ". A string
"Tentativa de lançar: {e}" parece estar interpolada. Devido ao caractere
$ ausente, a representação em cadeia da exceção
e não será substituída na cadeia. Como resultado, a string será usada "como está".
Terceiro lugar: "Não há saída"
V3008 [CWE-563] A variável 'this.linker.s3.region' recebe valores duas vezes sucessivamente. Talvez isso seja um erro. Verifique as linhas: 116, 114. AWSSDK.DynamoDBv2.Net45 S3Link.cs 116
public string Region { get { .... } set { if (String.IsNullOrEmpty(value)) { this.linker.s3.region = "us-east-1"; } this.linker.s3.region = value; } }
Erro do artigo "
Procurando erros no código-fonte do Amazon Web Services SDK para .NET ". No corpo do bloco
if , o
retorno foi ignorado. Como resultado, a variável
this.linker.s3.region sempre obterá
valor , incluindo uma cadeia vazia e
nula .
Segundo lugar: "Torne-se em ordem!"
V3070 A variável não inicializada 'LANG_USER_DEFAULT' é usada ao inicializar a variável 'LOCALE_USER_DEFAULT'. NativeMethods.cs 890
internal static class NativeMethods { .... public static readonly int LOCALE_USER_DEFAULT = MAKELCID(LANG_USER_DEFAULT); public static readonly int LANG_USER_DEFAULT = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); .... }
Erro do artigo "
WinForms: erros, Holmes ". A ordem de inicialização dos campos da classe é misturada. Para calcular o valor do campo
LOCALE_USER_DEFAULT , use o campo
LANG_USER_DEFAULT , que ainda não foi inicializado e tem um valor igual a 0. A variável
LANG_USER_DEFAULT não é usada em nenhum outro lugar do código. Para entender o que esse erro leva, um programa de teste foi escrito contendo métodos do código WinForms. Por simplicidade, algumas constantes reais foram substituídas por seus valores reais:
internal static class NativeMethods { public static readonly int LOCALE_USER_DEFAULT = MAKELCID(LANG_USER_DEFAULT); public static readonly int LANG_USER_DEFAULT = MAKELANGID(0x00, 0x01); public static int MAKELANGID(int primary, int sub) { return ((((ushort)(sub)) << 10) | (ushort)(primary)); } public static int MAKELCID(int lgid) { return MAKELCID(lgid, 0x0); } public static int MAKELCID(int lgid, int sort) { return ((0xFFFF & lgid) | (((0x000f) & sort) << 16)); } } class Program { static void Main() { System.Console.WriteLine(NativeMethods.LOCALE_USER_DEFAULT); } }
Como resultado do lançamento, o seguinte será exibido no console: 0. Agora, corrigiremos o erro trocando a declaração dos
campos LOCALE_USER_DEFAULT e
LANG_USER_DEFAULT . O resultado do programa neste formulário: 1024.
Primeiro lugar: "Confie, mas verifique"
Em primeiro lugar, é sempre difícil. Deve haver algo extraordinário e muito interessante. Inicialmente, selecionei mais de vinte erros interessantes para este artigo, mas não havia nada digno de primeiro lugar entre eles. E então me lembrei de um artigo do meu colega Sergey Vasiliev, dedicado a um único erro. A vantagem desse erro é que ele afetou diretamente a operação do nosso analisador. Como Isso já está claro no título do artigo "
Histórico de como o PVS-Studio encontrou um erro na biblioteca usada em ... PVS-Studio ". Mais uma vez, a preguiça não foi cancelada. :) E aqui estou completamente envergonhado e não darei uma descrição do erro, mas me proponho a seguir o link do artigo e descobrir mais. Eu garanto - vale a pena. E o artigo é curto.
Conclusão
Espero que os erros tenham sido interessantes, mas o artigo não se cansou. Lembro que você sempre pode
fazer o download do analisador PVS-Studio para procurar erros em seus próprios projetos e de terceiros, para agradar a si mesmo, amigos e colegas. E que haja menos erros e mais tempo para o auto-aperfeiçoamento! :)
Você leu? Parabéns por passar para o próximo nível! Nos seguintes artigos de nosso blog, os melhores erros de 2019 em projetos
Java e
C ++ são destacados .

Se você deseja compartilhar este artigo com um público que fala inglês, use o link para a tradução: Sergey Khrenov.
Os 10 principais erros encontrados em projetos C # em 2019 .