Menu

False Positive: Out of bounds check

fuzzel
2018-05-09
2020-08-22
  • fuzzel

    fuzzel - 2018-05-09

    Hello,

    the following code snippet produces a false-positive for the out-of-bounds check:
    Assume you have some array that is MAX_COUNT long and you search the array in the way seen below.
    Cppcheck doesn't recognize that the boolean flag 'wasFound' is only set to true if the search value was found
    in the array and the index is in a valid range.
    It looks like Cppcheck just checks if the index can be MAX_COUNT which can be the case if the value wasn't found but the the boolean flag is still set to false.

    bool wasFound=false;
    int idx=0;
    for(idx=0; idx<MAX_COUNT; idx++)
    {
        if(some_array[idx]==0x42)
        {
            wasFound=true;
            break;
         }
    }
    
    if(wasFound)
    {
            int x = some_array[idx]; <------ out-of-bounds error
    }
    
     

    Last edit: fuzzel 2018-05-17
  • versat

    versat - 2018-05-09

    Can you please edit the post and mark the source code as such for example with tilde characters:

    ~~~c
    source code goes here
    ~~~

    Otherwise the shown source code might be different than intended.
    I can imagine that this is a false positive.

     
  • Robert Morin

    Robert Morin - 2018-05-09

    Hi,

    I got this problem too. I'm guessing cppcheck is considering the exit condition of the for() to be 'idx < MAX_COUNT' in this case the idx will be greater than MAX_COUNT.

    Since a 'break' was the exit condition, it's a false positive but this also indicate the 'wasFound' is not needed and the code 'int x = some_array[idx]' could be moved inside the for loop before the 'break'.

    Hope it help

     
  • Daniel Marjamäki

    Thanks.. I created ticket https://trac.cppcheck.net/ticket/8569

     
  • Jim Garrett

    Jim Garrett - 2018-05-23

    Not sure this helps any...

    I used https://www.tutorialspoint.com/compile_c_online.php to compile and execute.

    ~~~c

    include <stdio.h>

    int main () {

    define MAX_COUNT 10

    int wasFound=0;
    int some_array[MAX_COUNT];
    int idx=0;
    int x=0;
    for( idx=0; idx<MAX_COUNT; idx++)
    {
    some_array[idx] = 0x40;
    }
    some_array[8] = 0x42;
    for( idx=0; idx<MAX_COUNT; idx++)
    {
    if(some_array[idx]==0x42)
    {
    wasFound=1;
    break;
    }
    }

    if(wasFound)
    {
    x = some_array[idx]; //<------ out-of-bounds error
    }

      printf("wasFound: %d\n", wasFound);
      printf("idx:      %d\n", idx);
      printf("x:        %#4x\n", x);
    

    return 0;

    }
    ~~~c

    $gcc -o main *.c
    $main
    wasFound: 1
    idx: 8
    x: 0x42

    With line 14: //some_array[8] = 0x42;

    gives:

    $gcc -o main *.c
    $main
    wasFound: 0
    idx: 10
    x: 0

     
  • Michael Nicholas

    I found a similar issue with cppcheck 2.1
    ~~~c
    int32_t timeout = 5;
    do
    {
    printf("timeout %d\r\n",timeout);
    } while (timeout--);
    if (timeout < 0)
    {
    printf("timeout %d\r\n", timeout);
    }
    ~~~
    cppcheck incorrectly flags the if (timeout < 0) as always false, but it does occur (in this case always, but in the real code there would be additional code with a break in it or additional conditions on the while loop).
    If it were (--timeout) instead of (timeout--), cppcheck would be correct, so it seems cppcheck does not correctly handle the post increment or decrements for loop exits correctly.

     
  • Daniel Marjamäki

    Thanks! I can reproduce. I created https://trac.cppcheck.net/ticket/9845#ticket

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.