diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9bdb47c88..6c34b5665 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3164,8 +3164,24 @@ private: // strncpy doesn't 0-terminate first parameter if (Token::Match(&tok, "strncpy ( %var% ,")) { - init_strncpy(checks, tok.tokAt(2)); - return tok.next()->link(); + if (Token::Match(tok.tokAt(4), "%str% ,")) + { + if (Token::Match(tok.tokAt(6), "%num% )")) + { + const unsigned int len = Token::getStrLength(tok.tokAt(4)); + const unsigned int sz = MathLib::toLongNumber(tok.strAt(6)); + if (len>=sz) + { + init_strncpy(checks, tok.tokAt(2)); + return tok.next()->link(); + } + } + } + else + { + init_strncpy(checks, tok.tokAt(2)); + return tok.next()->link(); + } } if (Token::simpleMatch(&tok, "asm ( )")) diff --git a/test/testother.cpp b/test/testother.cpp index 226029682..926806105 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2065,6 +2065,22 @@ private: " strncat(a, s, 20);\n" "}\n"); ASSERT_EQUALS("[test.cpp:5]: (error) Dangerous usage of 'a' (strncpy doesn't always 0-terminate it)\n", errout.str()); + + checkUninitVar("void f()\n" + "{\n" + " char a[100];\n" + " strncpy(a, \"hello\", 3);\n" + " strncat(a, \"world\", 20);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (error) Dangerous usage of 'a' (strncpy doesn't always 0-terminate it)\n", errout.str()); + + checkUninitVar("void f()\n" + "{\n" + " char a[100];\n" + " strncpy(a, \"hello\", sizeof(a));\n" + " strncat(a, \"world\", 20);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); }