Skip to content

Commit 81a8337

Browse files
committed
fix
1 parent d96cc9f commit 81a8337

1 file changed

Lines changed: 26 additions & 10 deletions

File tree

lib/checkio.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -666,16 +666,20 @@ void CheckIOImpl::wrongfeofUsage(const Token * tok)
666666
// printf("", 1); // Too much arguments
667667
//---------------------------------------------------------------------------
668668

669-
static bool findFormat(nonneg int arg, const Token *firstArg,
669+
static bool findFormat(nonneg int arg, nonneg int argc, const Token *firstArg,
670670
const Token *&formatStringTok, const Token *&formatArgTok)
671671
{
672+
formatArgTok = firstArg;
673+
674+
for (int i = 0; i < argc && formatArgTok; ++i)
675+
formatArgTok = formatArgTok->nextArgument();
676+
672677
const Token* argTok = firstArg;
673678

674679
for (int i = 0; i < arg && argTok; ++i)
675680
argTok = argTok->nextArgument();
676681

677682
if (Token::Match(argTok, "%str% [,)]")) {
678-
formatArgTok = argTok->nextArgument();
679683
formatStringTok = argTok;
680684
return true;
681685
}
@@ -686,7 +690,6 @@ static bool findFormat(nonneg int arg, const Token *firstArg,
686690
(argTok->variable()->dimensions().size() == 1 &&
687691
argTok->variable()->dimensionKnown(0) &&
688692
argTok->variable()->dimension(0) != 0))) {
689-
formatArgTok = argTok->nextArgument();
690693
if (!argTok->values().empty()) {
691694
const auto value = std::find_if(
692695
argTok->values().cbegin(), argTok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue));
@@ -706,6 +709,17 @@ static inline bool typesMatch(const std::string& iToTest, const std::string& iTy
706709
return (iToTest == iTypename) || (iToTest == iOptionalPrefix + iTypename);
707710
}
708711

712+
static int getMaxArgNo(const Library::Function *func)
713+
{
714+
const auto &checks = func->argumentChecks;
715+
return std::max_element(checks.cbegin(), checks.cend(),
716+
[](const std::pair<int, Library::ArgumentChecks> &lhs,
717+
const std::pair<int, Library::ArgumentChecks> &rhs) {
718+
return lhs.first < rhs.first;
719+
}
720+
)->first;
721+
}
722+
709723
void CheckIOImpl::checkWrongPrintfScanfArguments()
710724
{
711725
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@@ -723,46 +737,48 @@ void CheckIOImpl::checkWrongPrintfScanfArguments()
723737
bool scan = false;
724738
bool scanf_s = false;
725739
int formatStringArgNo = -1;
740+
int argc = -1;
726741

727742
if (tok->strAt(1) == "(" && mSettings.library.formatstr_function(tok)) {
743+
argc = getMaxArgNo(mSettings.library.getFunction(tok));
728744
formatStringArgNo = mSettings.library.formatstr_argno(tok);
729745
scan = mSettings.library.formatstr_scan(tok);
730746
scanf_s = mSettings.library.formatstr_secure(tok);
731747
}
732748

733749
if (formatStringArgNo >= 0) {
734750
// formatstring found in library. Find format string and first argument belonging to format string.
735-
if (!findFormat(formatStringArgNo, tok->tokAt(2), formatStringTok, argListTok))
751+
if (!findFormat(formatStringArgNo, argc, tok->tokAt(2), formatStringTok, argListTok))
736752
continue;
737753
} else if (Token::simpleMatch(tok, "swprintf (")) {
738754
if (Token::Match(tok->tokAt(2)->nextArgument(), "%str%")) {
739755
// Find third parameter and format string
740-
if (!findFormat(1, tok->tokAt(2), formatStringTok, argListTok))
756+
if (!findFormat(1, 2, tok->tokAt(2), formatStringTok, argListTok))
741757
continue;
742758
} else {
743759
// Find fourth parameter and format string
744-
if (!findFormat(2, tok->tokAt(2), formatStringTok, argListTok))
760+
if (!findFormat(2, 3, tok->tokAt(2), formatStringTok, argListTok))
745761
continue;
746762
}
747763
} else if (isWindows && Token::Match(tok, "sprintf_s|swprintf_s (")) {
748764
// template <size_t size> int sprintf_s(char (&buffer)[size], const char *format, ...);
749-
if (findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) {
765+
if (findFormat(1, 2, tok->tokAt(2), formatStringTok, argListTok)) {
750766
if (!formatStringTok)
751767
continue;
752768
}
753769
// int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...);
754-
else if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) {
770+
else if (findFormat(2, 3, tok->tokAt(2), formatStringTok, argListTok)) {
755771
if (!formatStringTok)
756772
continue;
757773
}
758774
} else if (isWindows && Token::Match(tok, "_snprintf_s|_snwprintf_s (")) {
759775
// template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...);
760-
if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) {
776+
if (findFormat(2, 3, tok->tokAt(2), formatStringTok, argListTok)) {
761777
if (!formatStringTok)
762778
continue;
763779
}
764780
// int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...);
765-
else if (findFormat(3, tok->tokAt(2), formatStringTok, argListTok)) {
781+
else if (findFormat(3, 4, tok->tokAt(2), formatStringTok, argListTok)) {
766782
if (!formatStringTok)
767783
continue;
768784
}

0 commit comments

Comments
 (0)