Skip to content

Commit 3122205

Browse files
Refs #9173: Fix FN bufferAccessOutOfBounds (memset on array, &a[0]) (#8656)
1 parent 907f9a4 commit 3122205

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

lib/checkbufferoverrun.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,16 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons
556556
{
557557
if (!bufTok->valueType())
558558
return ValueFlow::Value(-1);
559-
if (bufTok->isUnaryOp("&"))
559+
560+
if (bufTok->isUnaryOp("&")) {
560561
bufTok = bufTok->astOperand1();
562+
if (Token::simpleMatch(bufTok, "[")) {
563+
const Token* index = bufTok->astOperand2();
564+
if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0))
565+
return ValueFlow::Value(-1);
566+
bufTok = bufTok->astOperand1();
567+
}
568+
}
561569
const Variable *var = bufTok->variable();
562570

563571
if (!var || var->dimensions().empty()) {

test/testbufferoverrun.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ class TestBufferOverrun : public TestFixture {
227227
TEST_CASE(buffer_overrun_35); //#2304
228228
TEST_CASE(buffer_overrun_36);
229229
TEST_CASE(buffer_overrun_37);
230+
TEST_CASE(buffer_overrun_38);
230231
TEST_CASE(buffer_overrun_errorpath);
231232
TEST_CASE(buffer_overrun_bailoutIfSwitch); // ticket #2378 : bailoutIfSwitch
232233
TEST_CASE(buffer_overrun_function_array_argument);
@@ -3507,6 +3508,39 @@ class TestBufferOverrun : public TestFixture {
35073508
ASSERT_EQUALS("", errout_str());
35083509
}
35093510

3511+
void buffer_overrun_38() { // #9173
3512+
check("void f() {\n"
3513+
" int a[10];\n"
3514+
" memset(&a[0], 0, 20 * sizeof(int));\n"
3515+
"}\n"
3516+
"void g() {\n"
3517+
" int a[10];\n"
3518+
" memset(&a[0], 0, 10 * sizeof(int));\n"
3519+
"}\n"
3520+
"void h() {\n"
3521+
" int a[10];\n"
3522+
" memset(&a[5], 0, 5 * sizeof(int));\n"
3523+
"}\n"
3524+
"void i() {\n"
3525+
" int a[10][10];\n"
3526+
" memset(&a[0][0], 0, 100 * sizeof(int));\n"
3527+
"}\n");
3528+
ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[0] [bufferAccessOutOfBounds]\n", errout_str());
3529+
3530+
check("void f() {\n"
3531+
" int a[10];\n"
3532+
" memset(&a[5], 0, 10 * sizeof(int));\n"
3533+
"}\n"
3534+
"void g() {\n"
3535+
" int a[1][1];\n"
3536+
" memset(&a[0][0], 0, 10 * sizeof(int));\n"
3537+
"}\n");
3538+
TODO_ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n"
3539+
"[test.cpp:7:12]: (error) Buffer is accessed out of bounds: &a[0][0] [bufferAccessOutOfBounds]\n",
3540+
"",
3541+
errout_str());
3542+
}
3543+
35103544
void buffer_overrun_errorpath() {
35113545
setMultiline();
35123546
Settings s = settings0;

0 commit comments

Comments
 (0)