From 5eee9af9744a5132f8af24b55026efa71c41680a Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Thu, 8 Oct 2009 16:27:46 +0300 Subject: [PATCH] sprintf counter improvements --- src/checkbufferoverrun.cpp | 42 ++++++++++++++++++++++++++++++-------- test/testbufferoverrun.cpp | 38 +++++++++++----------------------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index f5bae6aa2..d334bada3 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -771,7 +771,7 @@ void CheckBufferOverrun::bufferOverrun() //--------------------------------------------------------------------------- -int CheckBufferOverrun::countSprintfLength(const std::string &input_string, const std::list &/*parameters*/) +int CheckBufferOverrun::countSprintfLength(const std::string &input_string, const std::list ¶meters) { @@ -783,7 +783,8 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons std::string digits_string = ""; int digits = 0; int check_for_i_d_x_f = 0; - + std::list::const_iterator paramIter = parameters.begin(); + int parameterLength = 0; for (std::string::size_type i = 0; i != input_string.length(); i++) { @@ -807,12 +808,27 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons case 'E': case 'g': case 'o': - case 's': case 'u': case 'p': case 'n': - if (flag == 0) on_on_next = 1; + if (flag == 0) + { + on_on_next = 1; + if (paramIter != parameters.end()) ++paramIter; + } break; + case 's': + if (flag == 0) + { + if (paramIter != parameters.end() && *paramIter && (*paramIter)->str()[0] == '"') + parameterLength = Token::getStrLength(*paramIter); + + on_on_next = 1; + if (paramIter != parameters.end()) ++paramIter; + } + break; + + case '%': if (flag == 1) flag = 0; else @@ -830,12 +846,21 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons if (on_on_next == 1 && flag == 0) { - //std::cout << digits_string; - digits_string = digits_string.substr(1, digits_string.size()); - if (check_for_i_d_x_f == 1) digits += std::max(abs(atoi(digits_string.c_str())), 1); + int tempDigits = 0; + if (check_for_i_d_x_f == 1) + tempDigits = std::max(abs(atoi(digits_string.c_str())), 1); else - digits += abs(atoi(digits_string.c_str())); + tempDigits = abs(atoi(digits_string.c_str())); + + if (tempDigits < parameterLength) + digits += parameterLength; + else if (parameterLength <= tempDigits) + digits += tempDigits; + else + digits += parameterLength - tempDigits; + + parameterLength = 0; digits_string = ""; check_for_i_d_x_f = 0; @@ -863,7 +888,6 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons continue; } j++; - } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 3c5eee6d7..a1a916168 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1031,43 +1031,29 @@ private: ASSERT_EQUALS(10, CheckBufferOverrun::countSprintfLength("\\\\\\\\Hello%d \0Text\\\\\\\\", unknownParameter)); ASSERT_EQUALS(4, CheckBufferOverrun::countSprintfLength("%%%%%d", unknownParameter)); - + Token strTok; + strTok.str("\"12345\""); std::list stringAsParameter; - { - Token tok; - tok.str("\"12345\""); - stringAsParameter.push_back(&tok); - } - - TODO_ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("str%s", stringAsParameter)); - TODO_ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%-4s", stringAsParameter)); + stringAsParameter.push_back(&strTok); + ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("str%s", stringAsParameter)); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%-4s", stringAsParameter)); ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%-5s", stringAsParameter)); ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%-6s", stringAsParameter)); std::list intAsParameter; - { - Token tok; - tok.str("12345"); - stringAsParameter.push_back(&tok); - } - + Token numTok; + numTok.str("12345"); + stringAsParameter.push_back(&numTok); TODO_ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%02ld", intAsParameter)); ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%08ld", intAsParameter)); std::list multipleParams; - { - Token tok; - tok.str("\"12345\""); - multipleParams.push_back(&tok); - - multipleParams.push_back(0); - - tok.str("12345"); - multipleParams.push_back(&tok); - } - + multipleParams.push_back(&strTok); + multipleParams.push_back(0); + multipleParams.push_back(&numTok); TODO_ASSERT_EQUALS(15, CheckBufferOverrun::countSprintfLength("str%s%d%d", multipleParams)); ASSERT_EQUALS(26, CheckBufferOverrun::countSprintfLength("str%-6s%08ld%08ld", multipleParams)); + } void strncpy1()