| 554 | } |
| 555 | |
| 556 | void CheckIOImpl::checkWrongPrintfScanfArguments() |
| 557 | { |
| 558 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 559 | const bool isWindows = mSettings.platform.isWindows(); |
| 560 | |
| 561 | logChecker("CheckIO::checkWrongPrintfScanfArguments"); |
| 562 | |
| 563 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 564 | for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 565 | if (!tok->isName()) continue; |
| 566 | |
| 567 | const Token* argListTok = nullptr; // Points to first va_list argument |
| 568 | const Token* formatStringTok = nullptr; // Points to format string token |
| 569 | |
| 570 | bool scan = false; |
| 571 | bool scanf_s = false; |
| 572 | int formatStringArgNo = -1; |
| 573 | |
| 574 | if (tok->strAt(1) == "(" && mSettings.library.formatstr_function(tok)) { |
| 575 | formatStringArgNo = mSettings.library.formatstr_argno(tok); |
| 576 | scan = mSettings.library.formatstr_scan(tok); |
| 577 | scanf_s = mSettings.library.formatstr_secure(tok); |
| 578 | } |
| 579 | |
| 580 | if (formatStringArgNo >= 0) { |
| 581 | // formatstring found in library. Find format string and first argument belonging to format string. |
| 582 | if (!findFormat(formatStringArgNo, tok->tokAt(2), formatStringTok, argListTok)) |
| 583 | continue; |
| 584 | } else if (Token::simpleMatch(tok, "swprintf (")) { |
| 585 | if (Token::Match(tok->tokAt(2)->nextArgument(), "%str%")) { |
| 586 | // Find third parameter and format string |
| 587 | if (!findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) |
| 588 | continue; |
| 589 | } else { |
| 590 | // Find fourth parameter and format string |
| 591 | if (!findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) |
| 592 | continue; |
| 593 | } |
| 594 | } else if (isWindows && Token::Match(tok, "sprintf_s|swprintf_s (")) { |
| 595 | // template <size_t size> int sprintf_s(char (&buffer)[size], const char *format, ...); |
| 596 | if (findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) { |
| 597 | if (!formatStringTok) |
| 598 | continue; |
| 599 | } |
| 600 | // int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...); |
| 601 | else if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) { |
| 602 | if (!formatStringTok) |
| 603 | continue; |
| 604 | } |
| 605 | } else if (isWindows && Token::Match(tok, "_snprintf_s|_snwprintf_s (")) { |
| 606 | // template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...); |
| 607 | if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) { |
| 608 | if (!formatStringTok) |
| 609 | continue; |
| 610 | } |
| 611 | // int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...); |
| 612 | else if (findFormat(3, tok->tokAt(2), formatStringTok, argListTok)) { |
| 613 | if (!formatStringTok) |