Os 10 principais erros encontrados em projetos C # em 2019

Quadro 1

Olá a todos os fãs de bugs! O ano novo está chegando em breve, então é hora de fazer um balanço do ano que termina. Por tradição, temos o prazer de apresentar a lista principal de erros encontrados pela equipe do PVS-Studio em projetos C # abertos em 2019. Pronto? Então vamos indo.

Décimo lugar "Engane 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, // <= isFirstDisplayedColumn); // <= .... } 

O erro do artigo " WinForms: Erros, Holmes ". O analisador ressalta que quando dois últimos argumentos do método são misturados. Vejamos a declaração AdjustCellBorderStyle :

 public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle( DataGridViewAdvancedBorderStyledataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { .... } 

Parece que o analisador está certo. Muitas vezes, os desenvolvedores passam intencionalmente alguns argumentos em ordem inversa, por exemplo, para trocar variáveis. Mas não parece ser esse o caso. Primeiro, as variáveis ​​do tipo bool são misturadas. Em segundo lugar, não há nomes de métodos incomuns: não há "Troca" ou "Reverso". Além disso, não é tão difícil cometer um erro como este: as pessoas percebem de maneira diferente a ordem de intercalação "linha / coluna".

Nono lugar "Tão perto da eternidade"


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)); } 

O erro do artigo " Verificando o código do Orchard CMS for Bugs ". Houve um erro que levou a uma recursão infinita. Para entender a maneira como o erro foi cometido, é preciso considerar a sobrecarga do método TryValidateModel :

 public bool TryValidateModel(object model) { return _updateModel.TryValidateModel(model); } 

É provável que o primeiro caso também use essa chamada:

 public bool TryValidateModel(object model, string prefix) { return _updateModel.TryValidateModel(model, Prefix(prefix)); } 

O código compilado com êxito, porque _updateModel é do tipo IUpdateModel e a classe atual também implementa a interface IUpdateModel .

Oitavo lugar "Encontre-me se puder"


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"; // <= public const string Recurse = "Recursively list the children of the management group"; public const string ParentId = "Parent Id of the management group"; public const string GroupName = "Management Group Id"; // <= public const string DisplayName = "Display Name of the management group"; public const string Expand = "Expand the output to list the children of the management group"; public const string Force = "Force the action and skip confirmations"; public const string InputObject = "Input Object from the Get call"; public const string ParentObject = "Parent Object"; } 

O erro do artigo " Azure PowerShell: principalmente inofensivo ". O analisador suspeitou que a constante GroupName fosse inicializada por uma sequência incorreta. Provavelmente deve haver algo como "Nome do Grupo de Gerenciamento" . A criticidade desse erro ainda é questionável, mas o erro é definitivamente raro e difícil de detectar.

Sétimo lugar "Apenas subestimado"


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)); } } 

O erro do artigo " Verificando a interface de usuário da Telerik quanto à UWP como uma maneira de iniciar o PVS-Studio ". O resultado da classificação anterior será perdido devido a uma chamada repetida para OrderBy na coleção já classificada. É preciso usar o ThenBy neste caso:

 this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .ThenBy(c => c.RowItemInfo.LayoutInfo.Line)); 

Tais erros são cometidos por desatenção ou ignorância. Eu acho que copiar e colar é o culpado aqui.

Sexto lugar "O código está documentado", disseram


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; // nothing to remove. } .... return true; } 

O erro do artigo " Verificando o código-fonte do .NET Core Libraries pelo PVS-Studio Static Analyzer ". O método sempre retornará verdadeiro . Sim, é um erro, mas há outra coisa realmente curiosa. O método é seguido pelo comentário detalhado:

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 .

Preste atenção na última frase. Quem lê esses comentários? No entanto, se levarmos a sério, esse erro é facilmente insinuado, por exemplo, durante a refatoração ou depuração. Bem, os autores queriam verificar a variante quando o resultado do método é sempre verdadeiro, mas esqueciam de retornar tudo como estava antes.

Quinto lugar "Me indexe agora!"


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; } 

O erro do artigo " Verificando o código-fonte do .NET Core Libraries pelo PVS-Studio Static Analyzer ". Ao percorrer a coleção seq no loop for , o desenvolvedor usa por engano o acesso apenas ao seu primeiro elemento em todas as iterações (índice 0 em vez de i ).

Quarto lugar "Apenas um dólar a menos"


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}"); } } } 

O erro do artigo " Verificando o código-fonte do .NET Core Libraries pelo PVS-Studio Static Analyzer ". Aparentemente, a string "Tentativa de lançar: {e}" deve ser interpolada. Devido à falta do caractere $ , a representação de linha da exceção e não será inserida na string. Como resultado, a linha 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; } } 

O erro do artigo " Procurando por erros no código-fonte do Amazon Web Services SDK para .NET ". O retorno foi perdido no corpo do bloco if . Como resultado, a variável this.linker.s3.region sempre obterá valor, incluindo uma linha vazia e nula.

Segundo lugar "Vestido certo!"


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); .... } 

O erro do artigo " WinForms: Erros, Holmes ". A ordem de inicialização dos campos da classe está confusa. Para calcular o valor do campo LOCALE_USER_DEFAULT , é usado o campo LANG_USER_DEFAULT , que ainda não foi inicializado no momento e é 0. A variável não é usada em nenhum outro local do código. Para obter o que esse erro leva, um programa de teste inteiro contendo métodos do código WinForms foi gravado. Em vez de algumas constantes usadas, seus valores reais foram substituídos pela simplicidade:

 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 da execução, teremos o seguinte: 0. Agora, vamos corrigir o erro trocando a declaração dos campos LOCALE_USER_DEFAULT e LANG_USER_DEFAULT . Resultado da execução do programa: 1024.

Primeiro lugar "Primeira tentativa, depois confie"


Nunca é fácil com o primeiro lugar. Deve haver algo extraordinário e cativante aqui. Inicialmente, para este artigo, selecionei mais de vinte erros interessantes, mas não havia nada digno de primeiro lugar entre eles. Foi quando me lembrei do artigo do meu colega Sergey Vasiliev. O artigo elaborou apenas um único erro. A beleza desse erro é que ele influenciou diretamente o trabalho do nosso analisador. Como Você já pode obtê-lo no título do artigo: " A história de como o PVS-Studio encontrou um erro na biblioteca usada em ... PVS-Studio ". Aqui é onde me senti com preguiça de fornecer a descrição do erro e, portanto, sugeriria que você seguisse o link e descubra os detalhes. :) Eu garanto que vale a pena. Além disso, o artigo é curto.

Conclusão


Espero que os erros tenham sido excelentes para você e o artigo não tenha sido cansativo. Apenas para constar, você sempre pode fazer o download do analisador PVS-Studio para encontrar bugs em seus projetos e de terceiros para agradar a si mesmo, colegas e qualquer Tom, Dick ou Harry. Que os erros sejam menores e tempo para o auto-aperfeiçoamento - mais! :)

Você leu até o fim? Meus parabéns por alcançar o novo nível! Não perca nossos artigos sobre upcomimg em nosso blog - os melhores bugs em projetos Java e C ++ encontrados em 2019.

Quadro 2

Source: https://habr.com/ru/post/pt481174/


All Articles