Search code examples
c++cportabilityscanfcppcheck

When to quantify ignored pattern match in the C sscanf function


Cppcheck 1.67 raised a portability issue in my source code at this line:

sscanf(s, "%d%*[,;.]%d", &f, &a);

This is the message I got from it:

scanf without field width limits can crash with huge input data on some versions of libc.

The original intention of the format string was to accept one of three possible limiter chars between two integers, and today - thanks to Cppcheck[1] - I see that %*[,;.] accepts even strings of limiter chars. However I doubt that my format string may cause a crash, because the unlimited part is ignored.

Is there possibly an issue with a buffer overrun? ...maybe behind the scenes?


[1] How to get lost between farsightedness and blindness:

I tried to fix it by %1*[,;.] (after some API doc), but Cppcheck insisted in the issue, so I also tried %*1[,;.] with the same "success". Seems that I have to suppress it for now...


Solution

  • Congratulations on finding a bug in Cppcheck 1.67 (the current version).

    You have basically three workarounds:

    1. Just ignore the false positive.
    2. Rework your format (assign that field, possible as you only want to match one character).

      char tmp;
      if(3 != sscanf(s, "%d %c%d", &f, &tmp, &a) || tmp!=',' && tmp!=';' && tmp!= '.')
          goto error;
      
    3. Suppress the warning directly (preferably inline-suppressions):

      //cppcheck-suppress invalidscanf_libc
      if(2 != sscanf(s, "%d%1*[,;.]%d", &f, &a))
          goto error;
      

    Don't forget to report the error, as "defect / false positive", so you can retire and forget that workaround as fast as possible.