Fix 11088: False positive: Array index out of bounds (function pointer parameter is array) (#5200)

This commit is contained in:
Paul Fultz II 2023-06-27 03:44:11 -05:00 committed by GitHub
parent a0c4e20e2d
commit 63b7e6a283
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 0 deletions

View File

@ -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))) {

View File

@ -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"