From f2719ec6ca346e9db42e9b6b1046a87724c27d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 23 Apr 2017 10:51:31 +0200 Subject: [PATCH] Refactoring CheckString::sprintfOverlappingData. Use AST, isSameExpression(), getArguments(), .. --- Makefile | 2 +- lib/checkstring.cpp | 39 +++++++++++++++------------------------ 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 27bf781ba..c92f9387a 100644 --- a/Makefile +++ b/Makefile @@ -366,7 +366,7 @@ $(SRCDIR)/checksizeof.o: lib/checksizeof.cpp lib/cxx11emu.h lib/checksizeof.h li $(SRCDIR)/checkstl.o: lib/checkstl.cpp lib/cxx11emu.h lib/checkstl.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h lib/checknullpointer.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkstl.o $(SRCDIR)/checkstl.cpp -$(SRCDIR)/checkstring.o: lib/checkstring.cpp lib/cxx11emu.h lib/checkstring.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h lib/utils.h +$(SRCDIR)/checkstring.o: lib/checkstring.cpp lib/cxx11emu.h lib/checkstring.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h lib/astutils.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkstring.o $(SRCDIR)/checkstring.cpp $(SRCDIR)/checktype.o: lib/checktype.cpp lib/cxx11emu.h lib/checktype.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 09dd49933..5d0d05f9e 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -20,6 +20,7 @@ //--------------------------------------------------------------------------- #include "checkstring.h" #include "symboldatabase.h" +#include "astutils.h" #include "utils.h" //--------------------------------------------------------------------------- @@ -321,6 +322,7 @@ void CheckString::incorrectStringBooleanError(const Token *tok, const std::strin //--------------------------------------------------------------------------- // Overlapping source and destination passed to sprintf(). +// TODO: Library configuration for overlapping arguments //--------------------------------------------------------------------------- void CheckString::sprintfOverlappingData() { @@ -329,34 +331,23 @@ void CheckString::sprintfOverlappingData() for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { - // Get variable id of target buffer.. - unsigned int varid = 0; - - if (Token::Match(tok, "sprintf|snprintf|swprintf ( %var% ,")) - varid = tok->tokAt(2)->varId(); - - else if (Token::Match(tok, "sprintf|snprintf|swprintf ( %name% . %var% ,")) - varid = tok->tokAt(4)->varId(); - - else + if (!Token::Match(tok, "sprintf|snprintf|swprintf (")) continue; - // goto next argument - const Token *tok2 = tok->tokAt(2)->nextArgument(); + const std::vector args = getArguments(tok); - if (tok->str() == "snprintf" || tok->str() == "swprintf") { // Jump over second parameter for snprintf and swprintf - tok2 = tok2->nextArgument(); - if (!tok2) - continue; - } - - // is any source buffer overlapping the target buffer? - do { - if (Token::Match(tok2, "%varid% [,)]", varid)) { - sprintfOverlappingDataError(tok2, tok2->str()); - break; + const int formatString = Token::Match(tok, "sprintf") ? 1 : 2; + for (unsigned int argnr = formatString + 1; argnr < args.size(); ++argnr) { + bool same = isSameExpression(_tokenizer->isCPP(), + false, + args[0], + args[argnr], + _settings->library, + true); + if (same) { + sprintfOverlappingDataError(args[argnr], args[argnr]->expressionString()); } - } while (nullptr != (tok2 = tok2->nextArgument())); + } } } }