diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index 9092026ab..b17b3c1e1 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -258,6 +258,31 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co continue; } + // sprintf.. + if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% ,", varid)) + { + int len = 0; + for (const Token *tok2 = tok->tokAt(6); tok2 && tok2->str() != ")"; tok2 = tok2->next()) + { + if (tok2->aaaa0() == '\"') + { + len -= 2; + const char *str = tok->strAt(0); + while (*str) + { + if (*str == '\\') + ++str; + ++str; + ++len; + } + } + } + if (len > (int)size) + { + ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok)); + } + } + // Function call.. // It's not interesting to check what happens when the whole struct is diff --git a/src/checkbufferoverrun.h b/src/checkbufferoverrun.h index 0bf4f2fb6..58a5d1c5a 100644 --- a/src/checkbufferoverrun.h +++ b/src/checkbufferoverrun.h @@ -40,10 +40,10 @@ private: /** Check for buffer overruns - locate struct variables and check them with the .._CheckScope function */ void CheckBufferOverrun_StructVariable(); - + /** Check for buffer overruns - locate local function variables and check them with the .._CheckScope function */ void CheckBufferOverrun_LocalVariable(); - + /** Check for buffer overruns - this is the function that performs the actual checking */ void CheckBufferOverrun_CheckScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 63e351f2a..a08282138 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -83,6 +83,8 @@ private: TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_2); + TEST_CASE(sprintf1); + TEST_CASE(varid1); TEST_CASE(varid2); } @@ -359,6 +361,17 @@ private: } + void sprintf1() + { + check("void f()\n" + "{\n" + " char str[3];\n" + " sprintf(str, \"%s\", \"abc\");\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:4]: Buffer overrun\n"), errout.str()); + } + + void varid1() {