Fix issue 8431 and 8776: Size of constant string
Fixes these cases: ```cpp void f(void) { const std::string msg="xyz"; if(!msg.empty()){} // Always true } ``` And out of bounds access: ```cpp #include <string> char fstr1(){const std::string s = "<a><b>"; return s[42]; } wchar_t fwstr1(){const std::wstring s = L"<a><b>"; return s[42]; } ```
This commit is contained in:
parent
68e8253920
commit
c0c6f92221
|
@ -5257,7 +5257,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
|
||||||
// after assignment
|
// after assignment
|
||||||
for (const Scope *functionScope : symboldatabase->functionScopes) {
|
for (const Scope *functionScope : symboldatabase->functionScopes) {
|
||||||
for (const Token *tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) {
|
for (const Token *tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "[;{}] %var% = %str% ;")) {
|
if (Token::Match(tok, "%name%|;|{|} %var% = %str% ;")) {
|
||||||
const Token *containerTok = tok->next();
|
const Token *containerTok = tok->next();
|
||||||
if (containerTok && containerTok->valueType() && containerTok->valueType()->container && containerTok->valueType()->container->stdStringLike) {
|
if (containerTok && containerTok->valueType() && containerTok->valueType()->container && containerTok->valueType()->container->stdStringLike) {
|
||||||
ValueFlow::Value value(Token::getStrLength(containerTok->tokAt(2)));
|
ValueFlow::Value value(Token::getStrLength(containerTok->tokAt(2)));
|
||||||
|
|
|
@ -3176,6 +3176,19 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f() {\n"
|
||||||
|
" const std::string x=\"xyz\";\n"
|
||||||
|
" if(!x.empty()){}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (style) Condition '!x.empty()' is always true\n", errout.str());
|
||||||
|
|
||||||
|
check("std::string g();\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" const std::string msg = g();\n"
|
||||||
|
" if(!msg.empty()){}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f(int *array, int size ) {\n"
|
check("void f(int *array, int size ) {\n"
|
||||||
" for(int i = 0; i < size; ++i) {\n"
|
" for(int i = 0; i < size; ++i) {\n"
|
||||||
" if(array == 0)\n"
|
" if(array == 0)\n"
|
||||||
|
|
|
@ -290,6 +290,15 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("test.cpp:3:error:Out of bounds access in expression 's.begin()+x' because 's' is empty and 'x' may be non-zero.\n", errout.str());
|
ASSERT_EQUALS("test.cpp:3:error:Out of bounds access in expression 's.begin()+x' because 's' is empty and 'x' may be non-zero.\n", errout.str());
|
||||||
|
|
||||||
|
checkNormal("char fstr1(){const std::string s = \"<a><b>\"; return s[42]; }\n"
|
||||||
|
"wchar_t fwstr1(){const std::wstring s = L\"<a><b>\"; return s[42]; }\n");
|
||||||
|
ASSERT_EQUALS("test.cpp:1:error:Out of bounds access in 's[42]', if 's' size is 6 and '42' is 42\n"
|
||||||
|
"test.cpp:2:error:Out of bounds access in 's[42]', if 's' size is 6 and '42' is 42\n", errout.str());
|
||||||
|
|
||||||
|
checkNormal("char fstr1(){const std::string s = \"<a><b>\"; return s[1]; }\n"
|
||||||
|
"wchar_t fwstr1(){const std::wstring s = L\"<a><b>\"; return s[1]; }\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkNormal("int f() {\n"
|
checkNormal("int f() {\n"
|
||||||
" std::vector<int> v;\n"
|
" std::vector<int> v;\n"
|
||||||
" std::vector<int> * pv = &v;\n"
|
" std::vector<int> * pv = &v;\n"
|
||||||
|
|
Loading…
Reference in New Issue