diff --git a/cfg/std.cfg b/cfg/std.cfg
index 6c434b8715c..edf67e0534b 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -5030,7 +5030,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
-
@@ -5116,7 +5115,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
-
@@ -5233,7 +5231,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
-
diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp
index bdd18ee21d2..7d9cb6d36d2 100644
--- a/lib/checkbufferoverrun.cpp
+++ b/lib/checkbufferoverrun.cpp
@@ -604,6 +604,14 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
return bufSizeVal;
}
}
+ } else if (bufTok->tokType() == Token::Type::eString && bufTok->valueType()) {
+ ValueFlow::Value strSizeVal;
+ strSizeVal.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
+ const size_t charSize = bufTok->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee);
+ if (charSize > 0) {
+ strSizeVal.intvalue = Token::getStrArraySize(bufTok) * charSize;
+ return strSizeVal;
+ }
}
}
diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp
index f6a2e1a5ec1..2443635eb0e 100644
--- a/test/testbufferoverrun.cpp
+++ b/test/testbufferoverrun.cpp
@@ -229,6 +229,7 @@ class TestBufferOverrun : public TestFixture {
TEST_CASE(buffer_overrun_36);
TEST_CASE(buffer_overrun_37);
TEST_CASE(buffer_overrun_38);
+ TEST_CASE(buffer_overrun_39);
TEST_CASE(buffer_overrun_errorpath);
TEST_CASE(buffer_overrun_bailoutIfSwitch); // ticket #2378 : bailoutIfSwitch
TEST_CASE(buffer_overrun_function_array_argument);
@@ -3484,23 +3485,6 @@ class TestBufferOverrun : public TestFixture {
" (void)strxfrm(dest,src,3);\n" // <<
"}\n");
ASSERT_EQUALS("[test.cpp:6:19]: (error) Buffer is accessed out of bounds: dest [bufferAccessOutOfBounds]\n", errout_str());
- // source size is too small
- check("void f(void) {\n"
- " const char src[2] = \"ab\";\n"
- " char dest[3] = \"abc\";\n"
- " (void)strxfrm(dest,src,1);\n"
- " (void)strxfrm(dest,src,2);\n"
- " (void)strxfrm(dest,src,3);\n" // <<
- "}\n");
- ASSERT_EQUALS("[test.cpp:6:24]: (error) Buffer is accessed out of bounds: src [bufferAccessOutOfBounds]\n", errout_str());
- // source size is too small
- check("void f(void) {\n"
- " const char src[1] = \"a\";\n"
- " char dest[3] = \"abc\";\n"
- " (void)strxfrm(dest,src,1);\n"
- " (void)strxfrm(dest,src,2);\n" // <<
- "}\n");
- ASSERT_EQUALS("[test.cpp:5:24]: (error) Buffer is accessed out of bounds: src [bufferAccessOutOfBounds]\n", errout_str());
}
void buffer_overrun_33() { // #2019
@@ -3638,6 +3622,44 @@ class TestBufferOverrun : public TestFixture {
ASSERT_EQUALS("", errout_str());
}
+ void buffer_overrun_39() { // #11765
+ check("void f() {\n"
+ " char buf[10];\n"
+ " memcpy(buf, \"abc\", 4);\n"
+ "}\n");
+ ASSERT_EQUALS("", errout_str());
+
+ check("void f() {\n"
+ " char buf[128];\n"
+ " memcpy(buf, \"abc\", 5);\n"
+ "}\n");
+ ASSERT_EQUALS("[test.cpp:3:17]: (warning) Buffer is accessed out of bounds: \"abc\" [bufferAccessOutOfBounds]\n",
+ errout_str());
+
+ check("void f() {\n"
+ " char buf[128];\n"
+ " memcpy(buf, L\"abc\", 4 * sizeof(wchar_t));\n"
+ "}\n");
+ ASSERT_EQUALS("", errout_str());
+
+ check("void f() {\n"
+ " char buf[128];\n"
+ " memcpy(buf, L\"abc\", 4 * sizeof(wchar_t) + 1);\n"
+ "}\n");
+ ASSERT_EQUALS("[test.cpp:3:17]: (warning) Buffer is accessed out of bounds: L\"abc\" [bufferAccessOutOfBounds]\n",
+ errout_str());
+
+ check("int f(char* s) {\n"
+ " return memcmp(s, \"\\0\\0\\0\", 3);\n"
+ "}\n");
+ ASSERT_EQUALS("", errout_str());
+
+ check("int f(const char16_t* buf) {\n"
+ " return memcmp(buf, u\"abc\", 4 * sizeof(char16_t));\n"
+ "}\n");
+ ASSERT_EQUALS("", errout_str());
+ }
+
void buffer_overrun_errorpath() {
setMultiline();
Settings s = settings0;
@@ -4618,9 +4640,8 @@ class TestBufferOverrun : public TestFixture {
check("void f() {\n"
" mymemset(\"abc\", 0, 20);\n"
"}\n", settings);
- TODO_ASSERT_EQUALS("[test.cpp:2]: (error) Buffer is accessed out of bounds.\n",
- "",
- errout_str());
+ ASSERT_EQUALS("[test.cpp:2:12]: (warning) Buffer is accessed out of bounds: \"abc\" [bufferAccessOutOfBounds]\n",
+ errout_str());
check("void f() {\n"
" mymemset(temp, \"abc\", 4);\n"