diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index 3d2416496..acceac15e 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -832,7 +832,6 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons case 'f': case 'x': case 'X': - case 'd': case 'i': i_d_x_f_found = true; case 'c': @@ -843,6 +842,14 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons case 'u': case 'p': case 'n': + handleNextParameter = true; + if (paramIter != parameters.end()) ++paramIter; + break; + case 'd': + i_d_x_f_found = true; + if (paramIter != parameters.end() && *paramIter && (*paramIter)->str()[0] != '"') + parameterLength = (*paramIter)->str().length(); + handleNextParameter = true; if (paramIter != parameters.end()) ++paramIter; break; @@ -872,24 +879,31 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons if (i_d_x_f_found) tempDigits = std::max(static_cast(tempDigits), 1); - if (parameterLength > 0 && digits_string.find('.') != std::string::npos) + if (digits_string.find('.') != std::string::npos) { - // If parameter is known, then also the max length value const std::string endStr = digits_string.substr(digits_string.find('.') + 1); unsigned int maxLen = std::max(std::abs(std::atoi(endStr.c_str())), 1); - // Note, this does not work with e.g. floats the same way it - // works for strings. Needs fixing in the future. - if (parameterLength > maxLen) - parameterLength = maxLen; + if (input_string[i] == 's') + { + // For strings, the length after the dot "%.2s" will limit + // the length of the string. + if (parameterLength > maxLen) + parameterLength = maxLen; + } + else + { + // For integers, the length after the dot "%.2d" can + // increase required length + if (tempDigits < maxLen) + tempDigits = maxLen; + } } if (tempDigits < parameterLength) input_string_size += parameterLength; - else if (parameterLength <= tempDigits) - input_string_size += tempDigits; else - input_string_size += parameterLength - tempDigits; + input_string_size += tempDigits; parameterLength = 0; digits_string = ""; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index d5f84037b..021df8643 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1104,16 +1104,23 @@ private: std::list intAsParameter; Token numTok; numTok.str("12345"); - stringAsParameter.push_back(&numTok); - TODO_ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%02ld", intAsParameter)); + intAsParameter.push_back(&numTok); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%02ld", intAsParameter)); ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%08ld", intAsParameter)); - TODO_ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%.2d", intAsParameter)); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%.2d", intAsParameter)); ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%08.2d", intAsParameter)); + TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%x", intAsParameter)); + ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%4x", intAsParameter)); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%5x", intAsParameter)); + ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%.4x", intAsParameter)); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%.5x", intAsParameter)); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%1.5x", intAsParameter)); + ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%5.1x", intAsParameter)); std::list floatAsParameter; Token floatTok; floatTok.str("1.12345f"); - stringAsParameter.push_back(&floatTok); + floatAsParameter.push_back(&floatTok); TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%8.2f", floatAsParameter)); TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter)); @@ -1121,7 +1128,7 @@ private: std::list floatAsParameter2; Token floatTok2; floatTok2.str("100.12345f"); - stringAsParameter.push_back(&floatTok2); + floatAsParameter2.push_back(&floatTok2); TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter2)); TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%4.2f", floatAsParameter)); @@ -1130,7 +1137,7 @@ private: 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(15, CheckBufferOverrun::countSprintfLength("str%s%d%d", multipleParams)); ASSERT_EQUALS(26, CheckBufferOverrun::countSprintfLength("str%-6s%08ld%08ld", multipleParams)); }