@@ -454,7 +454,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
454454 }
455455 } else if (Token::Match (tok, " sprintf|fprintf|sscanf|fscanf|swscanf|fwprintf|fwscanf ( %any%" ) ||
456456 (Token::simpleMatch (tok, " swprintf (" ) && Token::Match (tok->tokAt (2 )->nextArgument (), " %str%" )) ||
457- (windows && Token::Match (tok, " sscanf_s|swscanf_s ( %any%" ))) {
457+ (windows && Token::Match (tok, " sscanf_s|swscanf_s|fscanf_s|fwscanf_s|fprintf_s|fwprintf_s ( %any%" ))) {
458458 const Token* formatStringTok = tok->tokAt (2 )->nextArgument (); // Find second parameter (format string)
459459 if (Token::Match (formatStringTok, " %str% [,)]" )) {
460460 argListTok = formatStringTok->nextArgument (); // Find third parameter (first argument of va_args)
@@ -492,7 +492,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
492492 }
493493
494494 // Count format string parameters..
495- bool scanf_s = windows ? Token::Match (tok, " scanf_s|wscanf_s|sscanf_s|swscanf_s" ) : false ;
495+ bool scanf_s = windows ? Token::Match (tok, " scanf_s|wscanf_s|sscanf_s|swscanf_s|fscanf_s|fwscanf_s " ) : false ;
496496 bool scan = Token::Match (tok, " sscanf|fscanf|scanf|swscanf|fwscanf|wscanf" ) || scanf_s;
497497 unsigned int numFormat = 0 ;
498498 unsigned int numSecure = 0 ;
@@ -661,7 +661,14 @@ void CheckIO::checkWrongPrintfScanfArguments()
661661 invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
662662 break ;
663663 case ' I' :
664- if (argInfo.typeToken ->str () != " long" || !argInfo.typeToken ->isLong ())
664+ if (specifier.find (" I64" ) != std::string::npos) {
665+ if (argInfo.typeToken ->str () != " long" || !argInfo.typeToken ->isLong ())
666+ invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
667+ } else if (specifier.find (" I32" ) != std::string::npos) {
668+ if (argInfo.typeToken ->str () != " int" || argInfo.typeToken ->isLong ())
669+ invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
670+ } else if (argInfo.typeToken ->originalName () != " ptrdiff_t" &&
671+ argInfo.typeToken ->originalName () != " size_t" )
665672 invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
666673 break ;
667674 case ' j' :
@@ -726,7 +733,13 @@ void CheckIO::checkWrongPrintfScanfArguments()
726733 invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, false );
727734 break ;
728735 case ' I' :
729- if (argInfo.typeToken ->str () != " long" || !argInfo.typeToken ->isLong ())
736+ if (specifier.find (" I64" ) != std::string::npos) {
737+ if (argInfo.typeToken ->str () != " long" || !argInfo.typeToken ->isLong ())
738+ invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, false );
739+ } else if (specifier.find (" I32" ) != std::string::npos) {
740+ if (argInfo.typeToken ->str () != " int" || argInfo.typeToken ->isLong ())
741+ invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, false );
742+ } else if (argInfo.typeToken ->originalName () != " ptrdiff_t" )
730743 invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, false );
731744 break ;
732745 case ' j' :
@@ -787,7 +800,13 @@ void CheckIO::checkWrongPrintfScanfArguments()
787800 invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
788801 break ;
789802 case ' I' :
790- if (argInfo.typeToken ->str () != " long" || !argInfo.typeToken ->isLong ())
803+ if (specifier.find (" I64" ) != std::string::npos) {
804+ if (argInfo.typeToken ->str () != " long" || !argInfo.typeToken ->isLong ())
805+ invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
806+ } else if (specifier.find (" I32" ) != std::string::npos) {
807+ if (argInfo.typeToken ->str () != " int" || argInfo.typeToken ->isLong ())
808+ invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
809+ } else if (argInfo.typeToken ->originalName () != " size_t" )
791810 invalidScanfArgTypeError_int (tok, numFormat, specifier, &argInfo, true );
792811 break ;
793812 case ' j' :
@@ -853,8 +872,10 @@ void CheckIO::checkWrongPrintfScanfArguments()
853872 done = true ;
854873 break ;
855874 case ' I' :
856- if (i+1 != formatString.end () && *(i+1 ) == ' 6' &&
857- i+2 != formatString.end () && *(i+2 ) == ' 4' ) {
875+ if ((i+1 != formatString.end () && *(i+1 ) == ' 6' &&
876+ i+2 != formatString.end () && *(i+2 ) == ' 4' ) ||
877+ (i+1 != formatString.end () && *(i+1 ) == ' 3' &&
878+ i+2 != formatString.end () && *(i+2 ) == ' 2' )) {
858879 specifier += *i++;
859880 specifier += *i++;
860881 if ((i+1 ) != formatString.end () && !isalpha (*(i+1 ))) {
@@ -865,9 +886,13 @@ void CheckIO::checkWrongPrintfScanfArguments()
865886 specifier += *i++;
866887 }
867888 } else {
868- specifier += *i;
869- invalidLengthModifierError (tok, numFormat, specifier);
870- done = true ;
889+ if ((i+1 ) != formatString.end () && !isalpha (*(i+1 ))) {
890+ specifier += *i;
891+ invalidLengthModifierError (tok, numFormat, specifier);
892+ done = true ;
893+ } else {
894+ specifier += *i++;
895+ }
871896 }
872897 break ;
873898 case ' h' :
@@ -1497,8 +1522,12 @@ void CheckIO::invalidScanfArgTypeError_int(const Token* tok, unsigned int numFor
14971522 errmsg << (isUnsigned ? " unsigned " : " " ) << " long long" ;
14981523 else
14991524 errmsg << (isUnsigned ? " unsigned " : " " ) << " long" ;
1500- } else if (specifier[0 ] == ' I' ) {
1525+ } else if (specifier.find (" I32" ) != std::string::npos) {
1526+ errmsg << (isUnsigned ? " unsigned " : " " ) << " __int32" ;
1527+ } else if (specifier.find (" I64" ) != std::string::npos) {
15011528 errmsg << (isUnsigned ? " unsigned " : " " ) << " __int64" ;
1529+ } else if (specifier[0 ] == ' I' ) {
1530+ errmsg << (isUnsigned ? " size_t" : " ptrdiff_t" );
15021531 } else if (specifier[0 ] == ' j' ) {
15031532 if (isUnsigned)
15041533 errmsg << " uintmax_t" ;
0 commit comments