Skip to content

Commit bc88bec

Browse files
Fix #14935 FN bufferAccessOutOfBounds (memset() in loop) (#8754)
1 parent f26de0c commit bc88bec

2 files changed

Lines changed: 20 additions & 7 deletions

File tree

lib/checkbufferoverrun.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -560,12 +560,18 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
560560
if (!bufTok->valueType())
561561
return ValueFlow::Value(-1);
562562

563+
MathLib::bigint index = 0;
563564
if (bufTok->isUnaryOp("&")) {
564565
bufTok = bufTok->astOperand1();
565566
if (Token::simpleMatch(bufTok, "[")) {
566-
const Token* index = bufTok->astOperand2();
567-
if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0))
568-
return ValueFlow::Value(-1);
567+
if (const Token* indexTok = bufTok->astOperand2()) {
568+
if (indexTok->hasKnownIntValue())
569+
index = indexTok->getKnownIntValue();
570+
else if (const ValueFlow::Value* maxValue = indexTok->getMaxValue(false))
571+
index = maxValue->intvalue;
572+
else
573+
return ValueFlow::Value(-1);
574+
}
569575
bufTok = bufTok->astOperand1();
570576
}
571577
}
@@ -600,10 +606,10 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
600606
v.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
601607

602608
if (var->isPointerArray())
603-
v.intvalue = dim * mSettings.platform.sizeof_pointer;
609+
v.intvalue = (dim - index) * mSettings.platform.sizeof_pointer;
604610
else {
605611
const size_t typeSize = bufTok->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee);
606-
v.intvalue = dim * typeSize;
612+
v.intvalue = (dim - index) * typeSize;
607613
}
608614

609615
return v;

test/testbufferoverrun.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3537,7 +3537,7 @@ class TestBufferOverrun : public TestFixture {
35373537
"}\n");
35383538
TODO_ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n"
35393539
"[test.cpp:7:12]: (error) Buffer is accessed out of bounds: &a[0][0] [bufferAccessOutOfBounds]\n",
3540-
"",
3540+
"[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n",
35413541
errout_str());
35423542

35433543
check("void f() {\n" // #14866
@@ -3557,6 +3557,13 @@ class TestBufferOverrun : public TestFixture {
35573557
" fwrite(&s, 1, 1, fp);\n"
35583558
"}\n");
35593559
ASSERT_EQUALS("", errout_str()); // don't crash
3560+
3561+
check("void f() {\n" // #14935
3562+
" int a[5];\n"
3563+
" for (int i = 0; i < 5; ++i)\n"
3564+
" memset(&a[i], 0, sizeof(a));\n"
3565+
"}\n");
3566+
ASSERT_EQUALS("[test.cpp:4:16]: (error) Buffer is accessed out of bounds: &a[i] [bufferAccessOutOfBounds]\n", errout_str());
35603567
}
35613568

35623569
void buffer_overrun_errorpath() {
@@ -3814,7 +3821,7 @@ class TestBufferOverrun : public TestFixture {
38143821
" int i[10];\n"
38153822
" memset(&i[1], 0, 1000);\n"
38163823
"}");
3817-
TODO_ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: &i[1] [bufferAccessOutOfBounds]\n", "", errout_str());
3824+
ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: &i[1] [bufferAccessOutOfBounds]\n", errout_str());
38183825

38193826
check("struct S { int x; };\n" // #8616
38203827
"void f() {\n"

0 commit comments

Comments
 (0)