Home > database >  coverity STDIN dereference errors
coverity STDIN dereference errors

Time:09-16

In my C application I attempt to take in a single char from a user (no need to sanitize it) for commands. Functions such as getchar(), fgetc(stdin), and scanf(...) all give me the following error when used with coverity: Event dereference: Dereferencing "_stdin()", which is known to be "NULL". I use aggressiveness-level set to medium for the coverity-analyze command.

For example, I have tried checking cAck against NULL, stdin against NULL, ferror(stdin), and feof(stdin) before using the cAck variable. How would I make something like the following run without coverity complaints?

char cAck;
if( (cAck = fgetc(stdin)) != NULL)
{
// do something with cAck
}

CodePudding user response:

The message:

Event dereference: Dereferencing "_stdin()", which is known to be "NULL"

means that, somewhere in your code, you tested stdin against NULL, for example:

  if (stdin == NULL) {
    printf("stdin was NULL!\n");
    // but I kept going anyway, rather than aborting
  }

Indeed, you stated:

I have tried checking [...] stdin against NULL

Coverity sees this test, assumes the programmer is checking for a condition that might be true, and therefore concludes that it is possible that stdin is, in fact, NULL. Since (evidently, for your compiler) fgetc is a macro that dereferences stdin, Coverity then concludes that dereference could fail, leading to undefined behavior (typically a crash).

Although stdin has type FILE*, which is a pointer type, it is never NULL on startup, and attempting to set it to NULL is, itself, undefined behavior (see cppreference: stdin), so it is generally safe to assume that stdin is never NULL. Therefore, you should not confuse tools or other programmers by checking whether it is NULL.

That is, remove the check for stdin==NULL, and then Coverity should stop complaining.


Separately, as noted in comments, the return value of fgetc is int, so it is nonsensical to compare its return value to NULL, which is a pointer (to a first approximation at least). Instead, you probably want to compare it to the constant EOF:

char cAck;
if( (cAck = fgetc(stdin)) != EOF)
                          // ^^^ changed
{
// do something with cAck
}

CodePudding user response:

Since (evidently, for your compiler) fgetc is a macro that dereferences stdin

As Scott noted, this was basically the issue I was running into. I only tried checking stdin==NULL and returning after in hopes that it would see that stdin is not NULL for the rest of the code, but coverity complained with and without that check. As an aside, I believe coverity would additionally flag that as a FORWARD_NULL error if I checked that stdin was NULL and continued to use it.

Checking against EOF did not solve it. Fortunately, something as simple as the following code using scanf works well. Zero coverity errors.

char cAck;
scanf("%c", &cAck); 
  • Related