Skip to content

Commit b481511

Browse files
Fix #13496 fuzzing crash in CheckOther::checkIncompleteArrayFill(), use ValueFlow (#7167)
1 parent 0b5aa87 commit b481511

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

lib/checkother.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,8 +3203,11 @@ void CheckOther::checkIncompleteArrayFill()
32033203

32043204
for (const Scope * scope : symbolDatabase->functionScopes) {
32053205
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
3206-
if (Token::Match(tok, "memset|memcpy|memmove (") && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) {
3207-
const Token* tok2 = tok->tokAt(2);
3206+
if (Token::Match(tok, "memset|memcpy|memmove (")) {
3207+
std::vector<const Token*> args = getArguments(tok);
3208+
if (args.size() != 3)
3209+
continue;
3210+
const Token* tok2 = args[0];
32083211
if (tok2->str() == "::")
32093212
tok2 = tok2->next();
32103213
while (Token::Match(tok2, "%name% ::|."))
@@ -3216,19 +3219,19 @@ void CheckOther::checkIncompleteArrayFill()
32163219
if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0))
32173220
continue;
32183221

3219-
if (MathLib::toBigNumber(tok->linkAt(1)->tokAt(-1)) == var->dimension(0)) {
3220-
int size = mTokenizer->sizeOfType(var->typeStartToken());
3221-
if (size == 0 && var->valueType()->pointer)
3222-
size = mSettings->platform.sizeof_pointer;
3223-
else if (size == 0 && var->valueType())
3224-
size = ValueFlow::getSizeOf(*var->valueType(), *mSettings);
3225-
const Token* tok3 = tok->next()->astOperand2()->astOperand1()->astOperand1();
3226-
if ((size != 1 && size != 100 && size != 0) || var->isPointer()) {
3227-
if (printWarning)
3228-
incompleteArrayFillError(tok, tok3->expressionString(), tok->str(), false);
3229-
} else if (var->valueType()->type == ValueType::Type::BOOL && printPortability) // sizeof(bool) is not 1 on all platforms
3230-
incompleteArrayFillError(tok, tok3->expressionString(), tok->str(), true);
3231-
}
3222+
if (!args[2]->hasKnownIntValue() || args[2]->getKnownIntValue() != var->dimension(0))
3223+
continue;
3224+
int size = mTokenizer->sizeOfType(var->typeStartToken());
3225+
if (size == 0 && var->valueType()->pointer)
3226+
size = mSettings->platform.sizeof_pointer;
3227+
else if (size == 0 && var->valueType())
3228+
size = ValueFlow::getSizeOf(*var->valueType(), *mSettings);
3229+
const Token* tok3 = tok->next()->astOperand2()->astOperand1()->astOperand1();
3230+
if ((size != 1 && size != 100 && size != 0) || var->isPointer()) {
3231+
if (printWarning)
3232+
incompleteArrayFillError(tok, tok3->expressionString(), tok->str(), false);
3233+
} else if (var->valueType()->type == ValueType::Type::BOOL && printPortability) // sizeof(bool) is not 1 on all platforms
3234+
incompleteArrayFillError(tok, tok3->expressionString(), tok->str(), true);
32323235
}
32333236
}
32343237
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
f(){int a[5];memset(a,5)}

test/testother.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9562,6 +9562,13 @@ class TestOther : public TestFixture {
95629562
" memset(a, false, 5);\n"
95639563
"}");
95649564
ASSERT_EQUALS("[test.cpp:3]: (portability, inconclusive) Array 'a' might be filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'?\n", errout_str());
9565+
9566+
check("void f() {\n"
9567+
" const int n = 5;"
9568+
" int a[n];\n"
9569+
" memset(a, 0, n);\n"
9570+
"}");
9571+
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'?\n", errout_str());
95659572
}
95669573

95679574
void redundantVarAssignment() {

0 commit comments

Comments
 (0)