Improved countSprintfLength() to detect more errors with %d.

Fixed some errors from test cases.
Added more test cases.
This commit is contained in:
Reijo Tomperi 2009-10-20 00:48:29 +03:00
parent a36c31628d
commit 6fbf873d25
2 changed files with 37 additions and 16 deletions

View File

@ -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<int>(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 = "";

View File

@ -1104,16 +1104,23 @@ private:
std::list<const Token*> 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<const Token*> 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<const Token*> 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));
}