Fix 11088: False positive: Array index out of bounds (function pointer parameter is array) (#5200)
This commit is contained in:
parent
a0c4e20e2d
commit
63b7e6a283
|
@ -636,6 +636,36 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
|
|||
v.tokvalue = nullptr;
|
||||
return v;
|
||||
};
|
||||
functions["strcmp"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
const ValueFlow::Value& lhs = args[0];
|
||||
if (!(lhs.isTokValue() && lhs.tokvalue->tokType() == Token::eString))
|
||||
return ValueFlow::Value::unknown();
|
||||
const ValueFlow::Value& rhs = args[1];
|
||||
if (!(rhs.isTokValue() && rhs.tokvalue->tokType() == Token::eString))
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v(getStringLiteral(lhs.tokvalue->str()).compare(getStringLiteral(rhs.tokvalue->str())));
|
||||
ValueFlow::combineValueProperties(lhs, rhs, v);
|
||||
return v;
|
||||
};
|
||||
functions["strncmp"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 3)
|
||||
return ValueFlow::Value::unknown();
|
||||
const ValueFlow::Value& lhs = args[0];
|
||||
if (!(lhs.isTokValue() && lhs.tokvalue->tokType() == Token::eString))
|
||||
return ValueFlow::Value::unknown();
|
||||
const ValueFlow::Value& rhs = args[1];
|
||||
if (!(rhs.isTokValue() && rhs.tokvalue->tokType() == Token::eString))
|
||||
return ValueFlow::Value::unknown();
|
||||
const ValueFlow::Value& len = args[2];
|
||||
if (!len.isIntValue())
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v(getStringLiteral(lhs.tokvalue->str())
|
||||
.compare(0, len.intvalue, getStringLiteral(rhs.tokvalue->str()), 0, len.intvalue));
|
||||
ValueFlow::combineValueProperties(lhs, rhs, v);
|
||||
return v;
|
||||
};
|
||||
functions["sin"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 1)
|
||||
return ValueFlow::Value::unknown();
|
||||
|
@ -1164,6 +1194,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",")
|
||||
return expr->values().front();
|
||||
if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::TOK)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_END)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))) {
|
||||
|
|
|
@ -176,6 +176,7 @@ private:
|
|||
TEST_CASE(array_index_71); // #11461
|
||||
TEST_CASE(array_index_72); // #11784
|
||||
TEST_CASE(array_index_73); // #11530
|
||||
TEST_CASE(array_index_74); // #11088
|
||||
TEST_CASE(array_index_multidim);
|
||||
TEST_CASE(array_index_switch_in_for);
|
||||
TEST_CASE(array_index_for_in_for); // FP: #2634
|
||||
|
@ -1952,6 +1953,21 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// #11088
|
||||
void array_index_74()
|
||||
{
|
||||
check("void foo(const char *keys) {\n"
|
||||
" const char *prefix = \"<Shift+\";\n"
|
||||
" const size_t prefix_len = strlen(prefix);\n"
|
||||
" if (strncmp(keys, prefix, prefix_len)) { return; }\n"
|
||||
" if (keys[prefix_len] == '>') {}\n"
|
||||
"}\n"
|
||||
"void bar() {\n"
|
||||
" foo(\"q\");\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void array_index_multidim() {
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue