diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4ea104d77..2588d147b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5942,13 +5942,19 @@ bool Tokenizer::simplifyKnownVariables() ret |= simplifyKnownVariablesSimplify(&scopeStart, scopeStart, varid, structname, value, valueIsPointer, valueVarId, valueToken, -1); } - else if (Token::Match(tok2, "strcpy ( %var% , %str% ) ;")) { + else if (Token::Match(tok2, "strcpy|sprintf ( %var% , %str% ) ;")) { const unsigned int varid(tok2->tokAt(2)->varId()); + std::string::size_type n = -1; if (varid == 0) continue; const std::string structname(""); const Token * const valueToken = tok2->tokAt(4); std::string value(valueToken->str()); + if ((tok2->tokAt(0))->str() == "sprintf") { + while ((n = value.find("%%",n+1)) != std::string::npos) { + value.replace(n,2,"%"); + } + } const unsigned int valueVarId(0); const bool valueIsPointer(false); Token *tok3 = tok2; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 4c439fc0d..2abd36427 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -158,6 +158,7 @@ private: TEST_CASE(simplifyKnownVariables47); // ticket #3627 - >> TEST_CASE(simplifyKnownVariables48); // ticket #3754 - wrong simplification in for loop header TEST_CASE(simplifyKnownVariables49); // #3691 - continue in switch + TEST_CASE(simplifyKnownVariables50); // #4066 sprintf changes TEST_CASE(simplifyKnownVariablesIfEq1); // if (a==5) => a is 5 in the block TEST_CASE(simplifyKnownVariablesIfEq2); // if (a==5) { buf[a++] = 0; } TEST_CASE(simplifyKnownVariablesBailOutAssign1); @@ -2361,6 +2362,48 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Unspecified, "test.c")); } + void simplifyKnownVariables50() { // #4066 + { + const char code[] = "void f() {\n" + " char str1[10], str2[10];\n" + " sprintf(str1, \"%%\");\n" + " strcpy(str2, str1);\n" + "}"; + const char expected[] = "void f ( ) {\n" + "char str1 [ 10 ] ; char str2 [ 10 ] ;\n" + "sprintf ( str1 , \"%%\" ) ;\n" + "strcpy ( str2 , \"%\" ) ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); + } + { + const char code[] = "void f() {\n" + " char str1[25], str2[25];\n" + " sprintf(str1, \"abcdef%%%% and %% and %\");\n" + " strcpy(str2, str1);\n" + "}"; + const char expected[] = "void f ( ) {\n" + "char str1 [ 25 ] ; char str2 [ 25 ] ;\n" + "sprintf ( str1 , \"abcdef%%%% and %% and %\" ) ;\n" + "strcpy ( str2 , \"abcdef%% and % and %\" ) ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); + } + { + const char code[] = "void f() {\n" + " char str1[10], str2[10];\n" + " sprintf(str1, \"abc\");\n" + " strcpy(str2, str1);\n" + "}"; + const char expected[] = "void f ( ) {\n" + "char str1 [ 10 ] ; char str2 [ 10 ] ;\n" + "sprintf ( str1 , \"abc\" ) ;\n" + "strcpy ( str2 , \"abc\" ) ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); + } + } + void simplifyKnownVariablesIfEq1() { const char code[] = "void f(int x) {\n" " if (x==5) {\n"