--------------------------------------------------------------------------- Overlapping source and destination passed to sprintf(). TODO: Library configuration for overlapping arguments ---------------------------------------------------------------------------
| 421 | // TODO: Library configuration for overlapping arguments |
| 422 | //--------------------------------------------------------------------------- |
| 423 | void CheckStringImpl::sprintfOverlappingData() |
| 424 | { |
| 425 | logChecker("CheckString::sprintfOverlappingData"); |
| 426 | |
| 427 | const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 428 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 429 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 430 | if (!Token::Match(tok, "sprintf|snprintf|swprintf (")) |
| 431 | continue; |
| 432 | |
| 433 | const std::vector<const Token *> args = getArguments(tok); |
| 434 | |
| 435 | const int formatString = Token::simpleMatch(tok, "sprintf") ? 1 : 2; |
| 436 | for (unsigned int argnr = formatString + 1; argnr < args.size(); ++argnr) { |
| 437 | const Token *dest = args[0]; |
| 438 | while (dest->isCast()) |
| 439 | dest = dest->astOperand2() ? dest->astOperand2() : dest->astOperand1(); |
| 440 | const Token *arg = args[argnr]; |
| 441 | if (!arg->valueType() || arg->valueType()->pointer != 1) |
| 442 | continue; |
| 443 | while (arg->isCast()) |
| 444 | arg = arg->astOperand2() ? arg->astOperand2() : arg->astOperand1(); |
| 445 | |
| 446 | const bool same = isSameExpression(false, |
| 447 | dest, |
| 448 | arg, |
| 449 | mSettings, |
| 450 | true, |
| 451 | false); |
| 452 | if (same) { |
| 453 | sprintfOverlappingDataError(tok, args[argnr], arg->expressionString()); |
| 454 | } |
| 455 | } |
| 456 | } |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | void CheckStringImpl::sprintfOverlappingDataError(const Token *funcTok, const Token *tok, const std::string &varname) |
| 461 | { |
no test coverage detected