Fixed #4554 (false negative: buffer access out of bounds)

This commit is contained in:
Zachary Blair 2013-05-02 21:50:48 -07:00
parent bfb1bc50e3
commit de8ee5b042
4 changed files with 69 additions and 17 deletions

View File

@ -202,6 +202,10 @@ public:
_type == eBoolean; // TODO: "true"/"false" aren't really a name...
}
bool isUpperCaseName() const;
bool isLiteral() const {
return _type == eNumber || _type == eString || _type == eChar ||
_type == eBoolean || _type == eLiteral;
}
bool isNumber() const {
return _type == eNumber;
}

View File

@ -3369,23 +3369,8 @@ bool Tokenizer::simplifyTokenList()
// Simplify simple calculations..
simplifyCalculations();
// Replace "*(str + num)" => "str[num]"
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (!Token::Match(tok, "%var%") && !tok->isNumber()
&& !Token::Match(tok, "]|)")
&& (Token::Match(tok->next(), "* ( %var% + %num%|%var% )"))) {
// remove '* ('
tok->deleteNext(2);
tok = tok->tokAt(2);
// '+'->'['
tok->str("[");
tok = tok->tokAt(2);
tok->str("]");
Token::createMutualLinks(tok->tokAt(-2), tok);
}
}
// Replace "*(ptr + num)" => "ptr[num]"
simplifyOffsetPointerDereference();
// Replace "&str[num]" => "(str + num)"
std::set<unsigned int> pod;
@ -6760,8 +6745,39 @@ bool Tokenizer::simplifyCalculations()
return TemplateSimplifier::simplifyCalculations(list.front());
}
void Tokenizer::simplifyOffsetPointerDereference()
{
// Replace "*(str + num)" => "str[num]" and
// Replace "*(str - num)" => "str[-num]"
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (!tok->isName() && !tok->isLiteral()
&& !Token::Match(tok, "]|)|++|--")
&& Token::Match(tok->next(), "* ( %var% +|- %num%|%var% )")) {
// remove '* ('
tok->deleteNext(2);
// '+'->'['
tok = tok->tokAt(2);
Token* const openBraceTok = tok;
const bool isNegativeIndex = (tok->str() == "-");
tok->str("[");
// Insert a "-" in front of the number or variable
if (isNegativeIndex) {
if (tok->next()->isName()) {
tok->insertToken("-");
tok = tok->next();
} else
tok->next()->str(std::string("-") + tok->next()->str());
}
tok = tok->tokAt(2);
tok->str("]");
Token::createMutualLinks(openBraceTok, tok);
}
}
}
void Tokenizer::simplifyGoto()
{

View File

@ -165,6 +165,13 @@ public:
*/
bool simplifyCalculations();
/**
* Simplify dereferencing a pointer offset by a number:
* "*(ptr + num)" => "ptr[num]"
* "*(ptr - num)" => "ptr[-num]"
*/
void simplifyOffsetPointerDereference();
/** Insert array size where it isn't given */
void arraySize();

View File

@ -567,11 +567,36 @@ private:
ASSERT_EQUALS("; x = ( a + m ) & p [ n ] ;", tokenizeAndStringify("; x = ( a + m ) & p [ n ] ;", true));*/
// "*(p+1)" => "p[1]"
ASSERT_EQUALS("; x = p [ 1 ] ;", tokenizeAndStringify("; x = * ( p + 1 ) ;", true));
ASSERT_EQUALS("; x = p [ 10 ] ;", tokenizeAndStringify("; x = * ( p + 0xA ) ;", true));
ASSERT_EQUALS("; x = p [ n ] ;", tokenizeAndStringify("; x = * ( p + n ) ;", true));
ASSERT_EQUALS("; x = y * ( p + n ) ;", tokenizeAndStringify("; x = y * ( p + n ) ;", true));
ASSERT_EQUALS("; x = 10 * ( p + n ) ;", tokenizeAndStringify("; x = 10 * ( p + n ) ;", true));
ASSERT_EQUALS("; x = y [ 10 ] * ( p + n ) ;", tokenizeAndStringify("; x = y [ 10 ] * ( p + n ) ;", true));
ASSERT_EQUALS("; x = ( a + m ) * ( p + n ) ;", tokenizeAndStringify("; x = ( a + m ) * ( p + n ) ;", true));
// "*(p-1)" => "p[-1]" and "*(p-n)" => "p[-n]"
ASSERT_EQUALS("; x = p [ -1 ] ;", tokenizeAndStringify("; x = *(p - 1);", true));
ASSERT_EQUALS("; x = p [ -10 ] ;", tokenizeAndStringify("; x = *(p - 0xA);", true));
ASSERT_EQUALS("; x = p [ - n ] ;", tokenizeAndStringify("; x = *(p - n);", true));
ASSERT_EQUALS("; x = y * ( p - 1 ) ;", tokenizeAndStringify("; x = y * (p - 1);", true));
ASSERT_EQUALS("; x = 10 * ( p - 1 ) ;", tokenizeAndStringify("; x = 10 * (p - 1);", true));
ASSERT_EQUALS("; x = y [ 10 ] * ( p - 1 ) ;", tokenizeAndStringify("; x = y[10] * (p - 1);", true));
ASSERT_EQUALS("; x = ( a - m ) * ( p - n ) ;", tokenizeAndStringify("; x = (a - m) * (p - n);", true));
// Test that the array-index simplification is not applied when there's no dereference:
// "(x-y)" => "(x-y)" and "(x+y)" => "(x+y)"
ASSERT_EQUALS("; a = b * ( x - y ) ;", tokenizeAndStringify("; a = b * (x - y);", true));
ASSERT_EQUALS("; a = b * x [ - y ] ;", tokenizeAndStringify("; a = b * *(x - y);", true));
ASSERT_EQUALS("; a = a * ( x - y ) ;", tokenizeAndStringify("; a *= (x - y);", true));
ASSERT_EQUALS("; z = a ++ * ( x - y ) ;", tokenizeAndStringify("; z = a++ * (x - y);", true));
ASSERT_EQUALS("; z = a ++ * ( x + y ) ;", tokenizeAndStringify("; z = a++ * (x + y);", true));
ASSERT_EQUALS("; z = a -- * ( x - y ) ;", tokenizeAndStringify("; z = a-- * (x - y);", true));
ASSERT_EQUALS("; z = a -- * ( x + y ) ;", tokenizeAndStringify("; z = a-- * (x + y);", true));
ASSERT_EQUALS("; z = 'a' * ( x - y ) ;", tokenizeAndStringify("; z = 'a' * (x - y);", true));
ASSERT_EQUALS("; z = \"a\" * ( x - y ) ;", tokenizeAndStringify("; z = \"a\" * (x - y);", true));
ASSERT_EQUALS("; z = 'a' * ( x + y ) ;", tokenizeAndStringify("; z = 'a' * (x + y);", true));
ASSERT_EQUALS("; z = \"a\" * ( x + y ) ;", tokenizeAndStringify("; z = \"a\" * (x + y);", true));
ASSERT_EQUALS("; z = foo ( ) * ( x + y ) ;", tokenizeAndStringify("; z = foo() * (x + y);", true));
}
void tokenize7() {