From 5ec129e2a362d125e6d195a5795b60fb6b72cdda Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 17 Oct 2026 23:12:29 +0200 Subject: [PATCH 1/9] Fix #11765 FN: minsize not checked for string literal, buffer access out of bounds not found --- lib/checkbufferoverrun.cpp | 13 +++++++++-- lib/checkbufferoverrun.h | 2 +- test/cfg/posix.c | 3 ++- test/testbufferoverrun.cpp | 44 +++++++++++++++++++++++++++++++++++--- 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index bdd18ee21d2..e8de2adf547 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -558,7 +558,7 @@ void CheckBufferOverrunImpl::pointerArithmeticError(const Token *tok, const Toke //--------------------------------------------------------------------------- -ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, const Settings& settings) const +ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, const Settings& settings, bool checkStringLiteral) const { if (!bufTok->valueType()) return ValueFlow::Value(-1); @@ -604,6 +604,14 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons return bufSizeVal; } } + } else if (checkStringLiteral && 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; + } } } @@ -715,7 +723,8 @@ void CheckBufferOverrunImpl::bufferOverflow() if (argtok->valueType() && argtok->valueType()->pointer == 0) continue; // TODO: strcpy(buf+10, "hello"); - ValueFlow::Value bufferSize = getBufferSize(argtok, mSettings); + const bool strz = mSettings.library.isargstrz(tok, argnr + 1); + ValueFlow::Value bufferSize = getBufferSize(argtok, mSettings, !strz); if (bufferSize.intvalue <= 0) continue; // buffer size == 1 => do not warn for dynamic memory diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index b9b82c897e0..afac19d796c 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -129,7 +129,7 @@ class CPPCHECKLIB CheckBufferOverrunImpl : public CheckImpl void objectIndex(); void objectIndexError(const Token *tok, const ValueFlow::Value *v, bool known); - ValueFlow::Value getBufferSize(const Token *bufTok, const Settings& settings) const; + ValueFlow::Value getBufferSize(const Token *bufTok, const Settings& settings, bool checkStringLiteral = false) const; // CTU static bool isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset, int type); diff --git a/test/cfg/posix.c b/test/cfg/posix.c index 82cfd950792..ea69a6f4ab3 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -719,6 +719,7 @@ size_t bufferAccessOutOfBounds_strnlen(const char *s, size_t maxlen) size_t len = strnlen(buf,2); // cppcheck-suppress bufferAccessOutOfBounds len+=strnlen(buf,3); + len+=strnlen("ab",3); return len; } @@ -1606,4 +1607,4 @@ void pthread_define_test() (void)rwlock; PTHREAD_SCOPE_PROCESS; PTHREAD_SCOPE_SYSTEM; -} \ No newline at end of file +} diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index f6a2e1a5ec1..e5026a71330 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); @@ -3638,6 +3639,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 +4657,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" From 1fa524a1bbaf460f2cd0067ed34f32a9ed7a2af2 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sun, 18 Oct 2026 10:00:11 +0200 Subject: [PATCH 2/9] Fix --- cfg/posix.cfg | 2 ++ test/cfg/posix.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/cfg/posix.cfg b/cfg/posix.cfg index e0de433e1f1..70ba2582798 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -2123,11 +2123,13 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s + + diff --git a/test/cfg/posix.c b/test/cfg/posix.c index ea69a6f4ab3..e630dedc975 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -723,6 +723,12 @@ size_t bufferAccessOutOfBounds_strnlen(const char *s, size_t maxlen) return len; } +size_t bufferAccessOutOfBounds_strncasecmp(const char *s) +{ + size_t len = strncasecmp(s, "abc", 5); + return len; +} + void bufferAccessOutOfBounds_wcpncpy() { wchar_t s[16]; From 167421b1507ca4ec4713bf37a46b17b4862ba3a9 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sun, 18 Oct 2026 21:23:13 +0200 Subject: [PATCH 3/9] Fix --- cfg/gtk.cfg | 2 ++ cfg/posix.cfg | 2 ++ cfg/windows.cfg | 2 ++ lib/checkfunctions.cpp | 8 +++++++- test/cfg/posix.c | 8 +++++++- 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index a1d7763670e..3aee2e2b1a2 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -5386,11 +5386,13 @@ + + diff --git a/cfg/posix.cfg b/cfg/posix.cfg index 70ba2582798..e9a40c16b47 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -5608,6 +5608,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s + @@ -5784,6 +5785,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s + diff --git a/cfg/windows.cfg b/cfg/windows.cfg index b2251900d42..a7761ceb738 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -4293,11 +4293,13 @@ HFONT CreateFont( + + diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 0c5101750a6..18cfa3b7b89 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -102,6 +102,12 @@ void CheckFunctionsImpl::functionCalledError(const Token* tok, Severity severity reportError(tok, severity, prefix + "Called", msg, CWE477, Certainty::normal); } +static bool hasMinSize(const Token* ftok, int argnr, const Settings& settings) +{ + const auto minsizes = settings.library.argminsizes(ftok, argnr); + return minsizes && !minsizes->empty(); +} + //--------------------------------------------------------------------------- // Check , and //--------------------------------------------------------------------------- @@ -137,7 +143,7 @@ void CheckFunctionsImpl::invalidFunctionUsage() invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings.library.validarg(functionToken, argnr)); } // check - if (mSettings.library.isargstrz(functionToken, argnr)) { + if (mSettings.library.isargstrz(functionToken, argnr) && !hasMinSize(functionToken, argnr, mSettings)) { if (Token::Match(argtok, "& %var% !![") && argtok->next() && argtok->next()->valueType()) { const ValueType * valueType = argtok->next()->valueType(); const Variable * variable = argtok->next()->variable(); diff --git a/test/cfg/posix.c b/test/cfg/posix.c index e630dedc975..1018172a86a 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -194,6 +194,12 @@ void invalidFunctionArgStr_mbsnrtowcs(void) if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1 || wcscmp (wenough, L"AEF") != 0) {} } +int invalidFunctionArgStr_strncasecmp(const char* s) +{ + const char buf[3] = {'a', 'b', 'c'}; + return strncasecmp(buf, s, 3); +} + struct tm * ignoredReturnValue_localtime(const time_t *tp) { // cppcheck-suppress [ignoredReturnValue,localtimeCalled] @@ -719,7 +725,7 @@ size_t bufferAccessOutOfBounds_strnlen(const char *s, size_t maxlen) size_t len = strnlen(buf,2); // cppcheck-suppress bufferAccessOutOfBounds len+=strnlen(buf,3); - len+=strnlen("ab",3); + len+=strnlen("ab",5); return len; } From 558148b67eccfe97e45b4bcc2d76225f29ac6642 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sun, 18 Oct 2026 22:02:44 +0200 Subject: [PATCH 4/9] Fix --- lib/checkfunctions.cpp | 2 +- test/cfg/std.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 18cfa3b7b89..532b5a46c7e 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -104,7 +104,7 @@ void CheckFunctionsImpl::functionCalledError(const Token* tok, Severity severity static bool hasMinSize(const Token* ftok, int argnr, const Settings& settings) { - const auto minsizes = settings.library.argminsizes(ftok, argnr); + const std::vector* minsizes = settings.library.argminsizes(ftok, argnr); return minsizes && !minsizes->empty(); } diff --git a/test/cfg/std.c b/test/cfg/std.c index 997f8204f73..21bf2df4068 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -4000,11 +4000,10 @@ void bufferAccessOutOfBounds_strxfrm(void) { const char src[3] = "abc"; char dest[1] = "a"; - // cppcheck-suppress invalidFunctionArgStr (void)strxfrm(dest,src,1); - // cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr] + // cppcheck-suppress [bufferAccessOutOfBounds] (void)strxfrm(dest,src,2); - // cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr] + // cppcheck-suppress [bufferAccessOutOfBounds] (void)strxfrm(dest,src,3); } From a372e8d80625925b2865501207be8a5c92a8624f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:17:30 +0200 Subject: [PATCH 5/9] Update std.c [skip ci] --- test/cfg/std.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cfg/std.c b/test/cfg/std.c index 21bf2df4068..5ac901cf46f 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -4912,6 +4912,10 @@ void invalidFunctionArgString(char c) char d='d'; /* cppcheck-suppress invalidFunctionArgStr */ (void)strcat(str,&d); + + /* cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr] */ + char c[] = { 'a', 'b', 'c' }; + (void)strcat(c, "def"); } void ignoredReturnValue_abs(int i) From 8dac77207fa17a1efecb815c8b4b32f2b1682220 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:21:12 +0200 Subject: [PATCH 6/9] Update checkfunctions.cpp --- lib/checkfunctions.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 532b5a46c7e..6d12b1a5d15 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -102,10 +102,14 @@ void CheckFunctionsImpl::functionCalledError(const Token* tok, Severity severity reportError(tok, severity, prefix + "Called", msg, CWE477, Certainty::normal); } -static bool hasMinSize(const Token* ftok, int argnr, const Settings& settings) +static bool hasArgMinSize(const Token* ftok, int argnr, const Settings& settings) { - const std::vector* minsizes = settings.library.argminsizes(ftok, argnr); - return minsizes && !minsizes->empty(); + if (const std::vector* minsizes = settings.library.argminsizes(ftok, argnr)) { + return std::any_of(minsizes->begin(), minsizes->end(), [](const Library::ArgumentChecks::MinSize& ms) { + return ms.type == Library::ArgumentChecks::MinSize::Type::ARGVALUE; + }); + } + return false; } //--------------------------------------------------------------------------- @@ -143,7 +147,7 @@ void CheckFunctionsImpl::invalidFunctionUsage() invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings.library.validarg(functionToken, argnr)); } // check - if (mSettings.library.isargstrz(functionToken, argnr) && !hasMinSize(functionToken, argnr, mSettings)) { + if (mSettings.library.isargstrz(functionToken, argnr) && !hasArgMinSize(functionToken, argnr, mSettings)) { if (Token::Match(argtok, "& %var% !![") && argtok->next() && argtok->next()->valueType()) { const ValueType * valueType = argtok->next()->valueType(); const Variable * variable = argtok->next()->variable(); From e1837410613a3e72eec920e3c002c908a929ebf2 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:28:23 +0200 Subject: [PATCH 7/9] Update std.c --- test/cfg/std.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cfg/std.c b/test/cfg/std.c index 5ac901cf46f..d8322d55dea 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -4914,8 +4914,8 @@ void invalidFunctionArgString(char c) (void)strcat(str,&d); /* cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr] */ - char c[] = { 'a', 'b', 'c' }; - (void)strcat(c, "def"); + char a[] = { 'a', 'b', 'c' }; + (void)strcat(a, "def"); } void ignoredReturnValue_abs(int i) From 062dd28010e71258fa81575080c38dd4599a68a3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:45:15 +0200 Subject: [PATCH 8/9] Update std.c --- test/cfg/std.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cfg/std.c b/test/cfg/std.c index d8322d55dea..5f9c9d12a30 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -4913,8 +4913,8 @@ void invalidFunctionArgString(char c) /* cppcheck-suppress invalidFunctionArgStr */ (void)strcat(str,&d); - /* cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr] */ char a[] = { 'a', 'b', 'c' }; + /* cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr] */ (void)strcat(a, "def"); } From bb3c7f83583b90c114e92abe7bca0f6c4455e3ca Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 19 Oct 2026 19:40:47 +0200 Subject: [PATCH 9/9] Fix severity, use index, fix config, restore warning --- cfg/posix.cfg | 2 ++ cfg/windows.cfg | 2 ++ lib/checkbufferoverrun.cpp | 3 ++- lib/checkfunctions.cpp | 14 ++++++++------ test/cfg/std.c | 3 +++ test/testbufferoverrun.cpp | 12 +++++++++--- 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/cfg/posix.cfg b/cfg/posix.cfg index e9a40c16b47..14fe20f5dca 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -2148,11 +2148,13 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s + + diff --git a/cfg/windows.cfg b/cfg/windows.cfg index a7761ceb738..03c9fc9c70e 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -4319,11 +4319,13 @@ HFONT CreateFont( + + diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index e8de2adf547..bd1904c3394 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -606,10 +606,11 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons } } else if (checkStringLiteral && bufTok->tokType() == Token::Type::eString && bufTok->valueType()) { ValueFlow::Value strSizeVal; + strSizeVal.setKnown(); 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; + strSizeVal.intvalue = (Token::getStrArraySize(bufTok) - index) * charSize; return strSizeVal; } } diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 6d12b1a5d15..af59e18432d 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -102,12 +102,14 @@ void CheckFunctionsImpl::functionCalledError(const Token* tok, Severity severity reportError(tok, severity, prefix + "Called", msg, CWE477, Certainty::normal); } -static bool hasArgMinSize(const Token* ftok, int argnr, const Settings& settings) +static bool hasArgMinReadSize(const Token *ftok, int argnr, const Library &library) { - if (const std::vector* minsizes = settings.library.argminsizes(ftok, argnr)) { - return std::any_of(minsizes->begin(), minsizes->end(), [](const Library::ArgumentChecks::MinSize& ms) { - return ms.type == Library::ArgumentChecks::MinSize::Type::ARGVALUE; - }); + if (library.getArgDirection(ftok, argnr) == Library::ArgumentChecks::Direction::DIR_IN) { + if (const std::vector *minsizes = library.argminsizes(ftok, argnr)) { + return std::any_of(minsizes->begin(), minsizes->end(), [](const Library::ArgumentChecks::MinSize &ms) { + return ms.type == Library::ArgumentChecks::MinSize::Type::ARGVALUE; + }); + } } return false; } @@ -147,7 +149,7 @@ void CheckFunctionsImpl::invalidFunctionUsage() invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings.library.validarg(functionToken, argnr)); } // check - if (mSettings.library.isargstrz(functionToken, argnr) && !hasArgMinSize(functionToken, argnr, mSettings)) { + if (mSettings.library.isargstrz(functionToken, argnr) && !hasArgMinReadSize(functionToken, argnr, mSettings.library)) { if (Token::Match(argtok, "& %var% !![") && argtok->next() && argtok->next()->valueType()) { const ValueType * valueType = argtok->next()->valueType(); const Variable * variable = argtok->next()->variable(); diff --git a/test/cfg/std.c b/test/cfg/std.c index 5f9c9d12a30..2f19e00a6a7 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -78,6 +78,9 @@ void invalidFunctionArgStr_strncat(void) // No warning is expected for strncat (str1, &src, 1); puts (str1); + char d[] = {'a','b','c'}; + // cppcheck-suppress invalidFunctionArgStr + strncat(d, "def", 1); } char * invalidFunctionArgStr_strpbrk( const char *p ) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index e5026a71330..bbbaf996a25 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3650,7 +3650,7 @@ class TestBufferOverrun : public TestFixture { " 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", + ASSERT_EQUALS("[test.cpp:3:17]: (error) Buffer is accessed out of bounds: \"abc\" [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" @@ -3663,7 +3663,7 @@ class TestBufferOverrun : public TestFixture { " 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", + ASSERT_EQUALS("[test.cpp:3:17]: (error) Buffer is accessed out of bounds: L\"abc\" [bufferAccessOutOfBounds]\n", errout_str()); check("int f(char* s) {\n" @@ -3675,6 +3675,12 @@ class TestBufferOverrun : public TestFixture { " return memcmp(buf, u\"abc\", 4 * sizeof(char16_t));\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int f(const char* buf) {\n" + " return memcmp(buf, &\"abc\"[2], 4 * sizeof(char));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:24]: (error) Buffer is accessed out of bounds: &\"abc\"[2] [bufferAccessOutOfBounds]\n", + errout_str()); } void buffer_overrun_errorpath() { @@ -4657,7 +4663,7 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " mymemset(\"abc\", 0, 20);\n" "}\n", settings); - ASSERT_EQUALS("[test.cpp:2:12]: (warning) Buffer is accessed out of bounds: \"abc\" [bufferAccessOutOfBounds]\n", + ASSERT_EQUALS("[test.cpp:2:12]: (error) Buffer is accessed out of bounds: \"abc\" [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n"