Fix #826 (False positive: sprintf with "f%s")
http://sourceforge.net/apps/trac/cppcheck/ticket/826
This commit is contained in:
parent
34fe032dbe
commit
aca743c9ed
|
@ -806,33 +806,35 @@ void CheckBufferOverrun::bufferOverrun()
|
|||
|
||||
int CheckBufferOverrun::countSprintfLength(const std::string &input_string, const std::list<const Token*> ¶meters)
|
||||
{
|
||||
int flag = 1;
|
||||
int second_flag = 0; // This is to check for %
|
||||
int input_string_size = 0;
|
||||
int on_on_next = 0;
|
||||
bool percentCharFound = false;
|
||||
int input_string_size = 1;
|
||||
bool handleNextParameter = false;
|
||||
std::string digits_string = "";
|
||||
int digits = 0;
|
||||
int check_for_i_d_x_f = 0;
|
||||
bool i_d_x_f_found = false;
|
||||
std::list<const Token*>::const_iterator paramIter = parameters.begin();
|
||||
unsigned int parameterLength = 0;
|
||||
for (std::string::size_type i = 0; i != input_string.length(); i++)
|
||||
for (std::string::size_type i = 0; i < input_string.length(); ++i)
|
||||
{
|
||||
if (input_string[i] == '\\')
|
||||
{
|
||||
if (input_string[i+1] == '0')
|
||||
break;
|
||||
|
||||
if (on_on_next == 1)
|
||||
{
|
||||
flag = 1;
|
||||
on_on_next = 0;
|
||||
++input_string_size;
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (percentCharFound)
|
||||
{
|
||||
switch (input_string[i])
|
||||
{
|
||||
case '\\':
|
||||
if (input_string[i+1] == '0') break;
|
||||
case 'f':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'd':
|
||||
case 'i':
|
||||
check_for_i_d_x_f = 1;
|
||||
i_d_x_f_found = true;
|
||||
case 'c':
|
||||
case 'e':
|
||||
case 'E':
|
||||
|
@ -841,47 +843,34 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons
|
|||
case 'u':
|
||||
case 'p':
|
||||
case 'n':
|
||||
if (flag == 0)
|
||||
{
|
||||
on_on_next = 1;
|
||||
handleNextParameter = true;
|
||||
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;
|
||||
handleNextParameter = true;
|
||||
if (paramIter != parameters.end()) ++paramIter;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case '%':
|
||||
if (flag == 1) flag = 0;
|
||||
else
|
||||
if (input_string[i] == '%')
|
||||
percentCharFound = !percentCharFound;
|
||||
else if (percentCharFound)
|
||||
{
|
||||
flag = 1;
|
||||
digits_string.append(1, input_string[i]);
|
||||
}
|
||||
|
||||
if (!percentCharFound)
|
||||
input_string_size++;
|
||||
second_flag = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (flag && !second_flag) input_string_size++;
|
||||
else
|
||||
digits_string += input_string[i];
|
||||
|
||||
if (on_on_next == 1 && flag == 0)
|
||||
if (handleNextParameter)
|
||||
{
|
||||
digits_string = digits_string.substr(1, digits_string.size());
|
||||
unsigned int tempDigits = 0;
|
||||
if (check_for_i_d_x_f == 1)
|
||||
tempDigits = std::max(std::abs(std::atoi(digits_string.c_str())), 1);
|
||||
else
|
||||
tempDigits = std::abs(std::atoi(digits_string.c_str()));
|
||||
unsigned int tempDigits = std::abs(std::atoi(digits_string.c_str()));
|
||||
if (i_d_x_f_found)
|
||||
tempDigits = std::max(static_cast<int>(tempDigits), 1);
|
||||
|
||||
if (parameterLength > 0 && digits_string.find('.') != std::string::npos)
|
||||
{
|
||||
|
@ -896,45 +885,21 @@ int CheckBufferOverrun::countSprintfLength(const std::string &input_string, cons
|
|||
}
|
||||
|
||||
if (tempDigits < parameterLength)
|
||||
digits += parameterLength;
|
||||
input_string_size += parameterLength;
|
||||
else if (parameterLength <= tempDigits)
|
||||
digits += tempDigits;
|
||||
input_string_size += tempDigits;
|
||||
else
|
||||
digits += parameterLength - tempDigits;
|
||||
input_string_size += parameterLength - tempDigits;
|
||||
|
||||
parameterLength = 0;
|
||||
|
||||
digits_string = "";
|
||||
check_for_i_d_x_f = 0;
|
||||
i_d_x_f_found = false;
|
||||
percentCharFound = false;
|
||||
handleNextParameter = false;
|
||||
}
|
||||
second_flag = 0;
|
||||
|
||||
}
|
||||
|
||||
// A second iteration through the string to deal with /'s
|
||||
|
||||
std::string::size_type j = 0;
|
||||
|
||||
while (j < input_string.size())
|
||||
{
|
||||
|
||||
if (input_string[j] == '\\' && input_string[j+1] == '0')
|
||||
{
|
||||
input_string_size++;
|
||||
break;
|
||||
}
|
||||
if (input_string[j] == '\\')
|
||||
{
|
||||
input_string_size--;
|
||||
j += 2;
|
||||
continue;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
|
||||
return input_string_size + 1 + digits;
|
||||
|
||||
return input_string_size;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1075,13 +1075,16 @@ private:
|
|||
ASSERT_EQUALS(2, CheckBufferOverrun::countSprintfLength("%1d", unknownParameter));
|
||||
ASSERT_EQUALS(3, CheckBufferOverrun::countSprintfLength("%2.2d", unknownParameter));
|
||||
ASSERT_EQUALS(1, CheckBufferOverrun::countSprintfLength("%s", unknownParameter));
|
||||
ASSERT_EQUALS(2, CheckBufferOverrun::countSprintfLength("f%s", unknownParameter));
|
||||
ASSERT_EQUALS(1, CheckBufferOverrun::countSprintfLength("%-s", unknownParameter));
|
||||
ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%-5s", unknownParameter));
|
||||
ASSERT_EQUALS(2, CheckBufferOverrun::countSprintfLength("\\\"", unknownParameter));
|
||||
ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("Hello \0Text", unknownParameter));
|
||||
ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("Hello \\0Text", unknownParameter));
|
||||
ASSERT_EQUALS(1, CheckBufferOverrun::countSprintfLength("\\0", unknownParameter));
|
||||
ASSERT_EQUALS(2, CheckBufferOverrun::countSprintfLength("%%", unknownParameter));
|
||||
ASSERT_EQUALS(3, CheckBufferOverrun::countSprintfLength("%d%d", unknownParameter));
|
||||
ASSERT_EQUALS(10, CheckBufferOverrun::countSprintfLength("\\\\\\\\Hello%d \0Text\\\\\\\\", unknownParameter));
|
||||
ASSERT_EQUALS(3, CheckBufferOverrun::countSprintfLength("\\\\a%s\\0a", unknownParameter));
|
||||
ASSERT_EQUALS(10, CheckBufferOverrun::countSprintfLength("\\\\\\\\Hello%d \\0Text\\\\\\\\", unknownParameter));
|
||||
ASSERT_EQUALS(4, CheckBufferOverrun::countSprintfLength("%%%%%d", unknownParameter));
|
||||
|
||||
Token strTok;
|
||||
|
|
Loading…
Reference in New Issue