L'histoire de la façon dont PVS-Studio a trouvé une erreur dans la bibliothèque utilisée dans ... PVS-Studio

Image 1

Il s'agit d'une courte histoire sur la façon dont l'utilisation de PVS-Studio a permis de trouver une erreur dans le code source de la bibliothèque utilisée dans PVS-Studio. De plus, non théorique, mais réelle - l'erreur s'est manifestée dans la pratique lors de l'utilisation de la bibliothèque dans l'analyseur.

Dans PVS-Studio_Cmd (ainsi que certains autres utilitaires), nous utilisons une bibliothèque spéciale pour analyser les arguments de ligne de commande - CommandLine.

Aujourd'hui, j'étais engagé dans la prise en charge du nouveau mode dans PVS-Studio_Cmd, et il se trouve que j'ai dû utiliser cette bibliothèque d'arguments d'analyse. En train d'écrire du code, je le débogue également, car je dois travailler avec des API inconnues.

Ainsi, le code est écrit, compilé, exécuté pour exécution, ii ...

Image 3


L'exécution du code passe dans la bibliothèque où se produit une exception de type NullReferenceException . D'un côté, ce n'est pas très clair - je ne transmets aucune référence nulle explicite à la méthode.

Au cas où, je regarde les commentaires sur la méthode appelée. Il est très peu probable qu'ils décrivent les conditions d'une exception de type NullReferenceException (car généralement, comme il me semble, les exceptions de ce type sont imprévues).

Image 2


Dans les commentaires sur la méthode, il n'y a aucune information sur une NullReferenceException (qui, cependant, est attendue).

Afin de voir ce qui cause exactement l'exception (et où), j'ai décidé de télécharger le code source du projet, de compiler et de connecter la version de débogage de la bibliothèque à l'analyseur. Le code source du projet est disponible sur GitHub . La version 1.9.71 est requise, car c'est précisément ce type qui est maintenant utilisé dans l'analyseur.

Je charge la version appropriée du code source, collecte, connecte la bibliothèque de débogage à l'analyseur, exécute le code pour exécution et vois:

Image 4


Ainsi, la place de l'exception est claire - helpInfo est null , ce qui provoque une exception de type NullReferenceException lors de l'accès à la propriété d'instance Left .

Et puis je suis devenu pensif. Récemment, PVS-Studio pour C # a été assez bien amélioré dans divers domaines, y compris dans le domaine de la recherche de déréférencement de références potentiellement nulles. En particulier, l'analyse interprocédurale a été améliorée. Par conséquent, il est immédiatement devenu intéressant pour moi de vérifier le code source pour voir si PVS-Studio pouvait trouver l'erreur en cours de discussion.

J'ai vérifié le code source, et entre autres avertissements, j'ai vu exactement ce que j'espérais.

Avertissement PVS-Studio : V3080 Déréférence nulle possible à l'intérieur de la méthode à 'helpInfo.Left'. Pensez à inspecter le deuxième argument: helpInfo. Parser.cs 405

Oui, ça y est! Exactement ce dont vous avez besoin. Examinons le code source plus en détail.

private bool DoParseArgumentsVerbs( string[] args, object options, ref object verbInstance) { var verbs = ReflectionHelper.RetrievePropertyList<VerbOptionAttribute>(options); var helpInfo = ReflectionHelper.RetrieveMethod<HelpVerbOptionAttribute>(options); if (args.Length == 0) { if (helpInfo != null || _settings.HelpWriter != null) { DisplayHelpVerbText(options, helpInfo, null); // <= } return false; } .... } 

L'analyseur génère un message d'avertissement lors de l'appel de la méthode DisplayHelpVerbText et met en garde contre le deuxième argument - helpInfo . Notez que cette méthode se trouve dans la branche then de l' instruction if . L'expression conditionnelle est composée de telle manière que then- branch puisse être exécuté avec les valeurs de variables suivantes:

  • helpInfo == null ;
  • _settings.HelpWriter! = null ;

Voyons le corps de la méthode DisplayHelpVerbText :

 private void DisplayHelpVerbText( object options, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, string verb) { string helpText; if (verb == null) { HelpVerbOptionAttribute.InvokeMethod(options, helpInfo, null, out helpText); } else { HelpVerbOptionAttribute.InvokeMethod(options, helpInfo, verb, out helpText); } if (_settings.HelpWriter != null) { _settings.HelpWriter.Write(helpText); } } 

Depuis le verbe == null (voir l'appel de méthode), nous nous intéressons à la branche then- de l' instruction if . Bien que la situation avec la branche else soit similaire, nous considérerons la branche then , puisque dans notre cas particulier l'exécution a été effectuée à travers elle. N'oubliez pas que helpInfo peut être nul .

Examinons maintenant le corps de la méthode HelpVerbOptionAttribute.InvokeMethod . En fait, vous l'avez déjà vu dans la capture d'écran ci-dessus:

 internal static void InvokeMethod( object target, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, string verb, out string text) { text = null; var method = helpInfo.Left; if (!CheckMethodSignature(method)) { throw new MemberAccessException( SR.MemberAccessException_BadSignatureForHelpVerbOptionAttribute .FormatInvariant(method.Name)); } text = (string)method.Invoke(target, new object[] { verb }); } 

helpInfo.Left est appelé sans condition, même si helpInfo peut être null . L'analyseur en a averti et cela s'est produit.

Conclusion

Il s'est avéré drôle qu'avec l'aide de PVS-Studio, il était possible de trouver une erreur dans le code de la bibliothèque utilisée dans PVS-Studio. Je pense que c'est une sorte de suite de la réponse à la question "PVS-Studio trouve-t-il des erreurs dans le code PVS-Studio?". :) Il peut trouver des erreurs non seulement dans le code PVS-Studio, mais aussi dans le code des bibliothèques utilisées.

Enfin, je propose de télécharger l'analyseur et d'essayer de vérifier votre projet - que faire si vous y trouvez aussi quelque chose d'intéressant?



Si vous souhaitez partager cet article avec un public anglophone, veuillez utiliser le lien vers la traduction: Sergey Vasiliev. L'histoire de la façon dont PVS-Studio a trouvé une erreur dans la bibliothèque utilisée dans ... PVS-Studio

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


All Articles