﻿# The story of how PVS\-Studio found an error in the library used in\.\.\. PVS\-Studio

This is a short story about how PVS\-Studio helped us find an error in the source code of the library used in PVS\-Studio\. And it was not a theoretical error but an actual one \- the error appeared in practice when using the library in the analyzer\.

![0654_CMDParserBug/image1.png](https://import.viva64.com/docx/blog/0654_CMDParserBug/image1.png)

In PVS\-Studio\_Cmd \(as well as some other utilities\) we use a special library for parsing command line arguments \- CommandLine\.

Today I supported the new mode in PVS\-Studio\_Cmd and it so happened that I had to use this library for parsing command line arguments\. While writing the code, I also debug it because I have to work with unfamiliar APIs\.

So, the code is written, compiled, executed and\.\.\.

![0654_CMDParserBug/image2.png](https://import.viva64.com/docx/blog/0654_CMDParserBug/image2.png)

Code execution goes inside the library where an exception of the _NullReferenceException_ type occurs\. It's not so clear from the side \- I don't pass any null references into the method\.

To be sure, I look at comments to the callee method\. It is hardly probable that they describe the conditions of occurrence of an exception of the _NullReferenceException_ type \(as it seems to me usually  exceptions of this type are not provided for\)\.

![0654_CMDParserBug/image3.png](https://import.viva64.com/docx/blog/0654_CMDParserBug/image3.png)

There is no information about _NullReferenceException_ in the comments to the method \(which, however, is expected\)\.

To see what exactly causes the exception \(and where it occurs\), I decided to download the project's source code, build it and add a reference to the debug version of the library to the analyzer\. The source code of the project is [available at GitHub](https://github.com/commandlineparser/commandline)\. We need the version 1\.9\.71 of the library\. It is the one used in the analyzer now\.

I download the corresponding version of the source code, build the library, add a reference to the debug library to the analyzer, execute the code and see:

![0654_CMDParserBug/image4.png](https://import.viva64.com/docx/blog/0654_CMDParserBug/image4.png)

So, the place where the exception occurs is clear \- _helpInfo_ has a _null_ value, which causes an exception of the _NullReferenceException_ type when accessing the _Left_ property\.

I started thinking about it\. Recently, PVS\-Studio for C\# has been well improved in various aspects, including the search for dereferencing of potentially null references\. In particular, the interprocedural analysis was improved in a number of ways\. That's why I was immediately interested in checking the source code to understand if PVS\-Studio could find the error under discussion\.

I checked the source code and among other warnings I saw exactly what I hoped for\.

**PVS\-Studio warning**: [V3080](https://pvs-studio.com/en/docs/warnings/v3080/) Possible null dereference inside method at 'helpInfo\.Left'\. Consider inspecting the 2nd argument: helpInfo\. Parser\.cs 405

Yeah, this is it\! That's exactly what we need\. Let's take a more detailed look at the source code\.

```cpp
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;
  }
  ....
}
```

The analyzer issues a warning for calling the _DisplayHelpVerbText_ method and warns about the second argument \- _helpInfo_\. Pay attention that this method is located in the _then_\-branch of the _if_ statement\. The conditional expression is composed in such a way that the _then_\-branch can be executed at the next values of the variables:

* _helpInfo \=\= null_;
* _\_settings\.HelpWriter \!\= null_;

Let's see the body of the _DisplayHelpVerbText_ method:

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

Since _verb \=\= null_ \(see method call\) we are interested in _then_\-branch of the _if_ statement\. Although the situation is similar with the _else_ branch, let's consider _then_\-branch because in our particular case the execution went through it\. Remember that _helpInfo_ may be _null_\.

Now let's look at the body of the _HelpVerbOptionAttribute_\._InvokeMethod_ method\. Actually, you have already seen it on the screenshot above:

```cpp
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_ is called unconditionally, while _helpInfo_ may be _null_\. The analyzer warned about it, and that's what happened\.

**Conclusion**

It is nice that we managed to find an error in the source code of the library used in PVS\-Studio with the help of PVS\-Studio\. I think this is a kind of the answer to the question "Does PVS\-Studio find errors in PVS\-Studio source code?"\. :\) The analyzer can find errors not only in PVS\-Studio code but also in the code of the used libraries\.

Finally, I suggest you [download the analyzer](https://pvs-studio.com/en/pvs-studio/download/) and try to check your project \- what if you can find something interesting there too?