Skip to content

Commit 59de308

Browse files
IOBYTEdanmar
authored andcommitted
CheckIO: This patch adds support for fprintf_s, fscanf_s and %I. Ticket: danmar#5051
1 parent 022e7a0 commit 59de308

File tree

3 files changed

+218
-11
lines changed

3 files changed

+218
-11
lines changed

lib/checkio.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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";

lib/tokenize.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9604,6 +9604,9 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
96049604
tok->str("strstr");
96059605
} else if (Token::simpleMatch(tok, "_tcstok (")) {
96069606
tok->str("strtok");
9607+
} else if (Token::simpleMatch(tok, "_ftprintf (")) {
9608+
tok->str("fprintf");
9609+
tok->originalName("_ftprintf");
96079610
} else if (Token::simpleMatch(tok, "_tprintf (")) {
96089611
tok->str("printf");
96099612
tok->originalName("_tprintf");
@@ -9613,12 +9616,18 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
96139616
} else if (Token::simpleMatch(tok, "_sntprintf (")) {
96149617
tok->str("snprintf");
96159618
tok->originalName("_sntprintf");
9619+
} else if (Token::simpleMatch(tok, "_ftscanf (")) {
9620+
tok->str("fscanf");
9621+
tok->originalName("_ftscanf");
96169622
} else if (Token::simpleMatch(tok, "_tscanf (")) {
96179623
tok->str("scanf");
96189624
tok->originalName("_tscanf");
96199625
} else if (Token::simpleMatch(tok, "_stscanf (")) {
96209626
tok->str("sscanf");
96219627
tok->originalName("_stscanf");
9628+
} else if (Token::simpleMatch(tok, "_ftprintf_s (")) {
9629+
tok->str("fprintf_s");
9630+
tok->originalName("_ftprintf_s");
96229631
} else if (Token::simpleMatch(tok, "_tprintf_s (")) {
96239632
tok->str("printf_s");
96249633
tok->originalName("_tprintf_s");
@@ -9628,6 +9637,9 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
96289637
} else if (Token::simpleMatch(tok, "_sntprintf_s (")) {
96299638
tok->str("_snprintf_s");
96309639
tok->originalName("_sntprintf_s");
9640+
} else if (Token::simpleMatch(tok, "_ftscanf_s (")) {
9641+
tok->str("fscanf_s");
9642+
tok->originalName("_ftscanf_s");
96319643
} else if (Token::simpleMatch(tok, "_tscanf_s (")) {
96329644
tok->str("scanf_s");
96339645
tok->originalName("_tscanf_s");
@@ -9674,6 +9686,9 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
96749686
tok->str("wcsstr");
96759687
} else if (Token::simpleMatch(tok, "_tcstok (")) {
96769688
tok->str("wcstok");
9689+
} else if (Token::simpleMatch(tok, "_ftprintf (")) {
9690+
tok->str("fwprintf");
9691+
tok->originalName("_ftprintf");
96779692
} else if (Token::simpleMatch(tok, "_tprintf (")) {
96789693
tok->str("wprintf");
96799694
tok->originalName("_tprintf");
@@ -9683,12 +9698,18 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
96839698
} else if (Token::simpleMatch(tok, "_sntprintf (")) {
96849699
tok->str("snwprintf");
96859700
tok->originalName("_sntprintf");
9701+
} else if (Token::simpleMatch(tok, "_ftscanf (")) {
9702+
tok->str("fwscanf");
9703+
tok->originalName("_ftscanf");
96869704
} else if (Token::simpleMatch(tok, "_tscanf (")) {
96879705
tok->str("wscanf");
96889706
tok->originalName("_tscanf");
96899707
} else if (Token::simpleMatch(tok, "_stscanf (")) {
96909708
tok->str("swscanf");
96919709
tok->originalName("_stscanf");
9710+
} else if (Token::simpleMatch(tok, "_ftprintf_s (")) {
9711+
tok->str("fwprintf_s");
9712+
tok->originalName("_ftprintf_s");
96929713
} else if (Token::simpleMatch(tok, "_tprintf_s (")) {
96939714
tok->str("wprintf_s");
96949715
tok->originalName("_tprintf_s");
@@ -9698,6 +9719,9 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
96989719
} else if (Token::simpleMatch(tok, "_sntprintf_s (")) {
96999720
tok->str("_snwprintf_s");
97009721
tok->originalName("_sntprintf_s");
9722+
} else if (Token::simpleMatch(tok, "_ftscanf_s (")) {
9723+
tok->str("fwscanf_s");
9724+
tok->originalName("_ftscanf_s");
97019725
} else if (Token::simpleMatch(tok, "_tscanf_s (")) {
97029726
tok->str("wscanf_s");
97039727
tok->originalName("_tscanf_s");

0 commit comments

Comments
 (0)