⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checkbufferoverrun.cpp

📁 cppcheck is a static C/C++ code analyzer that checks for memory leaks, mismatching allocation-deallo
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                _errorLogger->bufferOverrun(_tokenizer, tok);            }        }        // snprintf..        if (varid > 0 && Token::Match(tok, "snprintf ( %varid% , %num%", varid))        {            int n = std::atoi(tok->strAt(4));            if (n > size)                _errorLogger->outOfBounds(_tokenizer, tok->tokAt(4), "snprintf size");        }        // cin..        if (varid > 0 && Token::Match(tok, "cin >> %varid% ;", varid))        {            _errorLogger->bufferOverrun(_tokenizer, tok);        }        // Function call..        // It's not interesting to check what happens when the whole struct is        // sent as the parameter, that is checked separately anyway.        if (Token::Match(tok, "%var% ("))        {            // Don't make recursive checking..            if (std::find(_callStack.begin(), _callStack.end(), tok) != _callStack.end())                continue;            // Only perform this checking if showAll setting is enabled..            if (!_settings._showAll)                continue;            unsigned int parlevel = 0, par = 0;            for (const Token *tok2 = tok; tok2; tok2 = tok2->next())            {                if (tok2->str() == "(")                {                    ++parlevel;                }                else if (tok2->str() == ")")                {                    --parlevel;                    if (parlevel < 1)                    {                        par = 0;                        break;                    }                }                else if (parlevel == 1 && (tok2->str() == ","))                {                    ++par;                }                if (parlevel == 1 && Token::Match(tok2, std::string("[(,] " + varnames + " [,)]").c_str()))                {                    ++par;                    break;                }            }            if (par == 0)                continue;            // Find function..            const Token *ftok = _tokenizer->GetFunctionTokenByName(tok->aaaa());            if (!ftok)                continue;            // Parse head of function..            ftok = ftok->tokAt(2);            parlevel = 1;            while (ftok && parlevel == 1 && par >= 1)            {                if (ftok->str() == "(")                    ++parlevel;                else if (ftok->str() == ")")                    --parlevel;                else if (ftok->str() == ",")                    --par;                else if (par == 1 && parlevel == 1 && Token::Match(ftok, "%var% [,)]"))                {                    // Parameter name..                    const char *parname[2];                    parname[0] = ftok->aaaa();                    parname[1] = 0;                    // Goto function body..                    while (ftok && (ftok->str() != "{"))                        ftok = ftok->next();                    ftok = ftok ? ftok->next() : 0;                    // Check variable usage in the function..                    _callStack.push_back(tok);                    CheckBufferOverrun_CheckScope(ftok, parname, size, total_size, 0);                    _callStack.pop_back();                    // break out..                    break;                }                ftok = ftok->next();            }        }    }}//---------------------------------------------------------------------------// Checking local variables in a scope//---------------------------------------------------------------------------void CheckBufferOverrunClass::CheckBufferOverrun_GlobalAndLocalVariable(){    int indentlevel = 0;    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        if (tok->str() == "{")            ++indentlevel;        else if (tok->str() == "}")            --indentlevel;        const char *varname[2] = {0};        unsigned int size = 0;        const char *type = 0;        unsigned int varid = 0;        int nextTok = 0;        if (Token::Match(tok, "%type% %var% [ %num% ] [;=]"))        {            varname[0] = tok->strAt(1);            size = std::strtoul(tok->strAt(3), NULL, 10);            type = tok->aaaa();            varid = tok->tokAt(1)->varId();            nextTok = 6;        }        else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))        {            varname[0] = tok->strAt(1);            size = std::strtoul(tok->strAt(6), NULL, 10);            type = tok->strAt(4);            varid = tok->tokAt(1)->varId();            nextTok = 8;        }        else        {            continue;        }        int total_size = size * _tokenizer->SizeOfType(type);        if (total_size == 0)            continue;        // The callstack is empty        _callStack.clear();        CheckBufferOverrun_CheckScope(tok->tokAt(nextTok), varname, size, total_size, varid);    }}//---------------------------------------------------------------------------//---------------------------------------------------------------------------// Checking member variables of structs..//---------------------------------------------------------------------------void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable(){    const char declstruct[] = "struct|class %var% {";    for (const Token *tok = Token::findmatch(_tokenizer->tokens(), declstruct);         tok; tok = Token::findmatch(tok->next(), declstruct))    {        const std::string &structname = tok->next()->str();        // Found a struct declaration. Search for arrays..        for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next())        {            if (tok2->str() == "}")                break;            int ivar = 0;            if (Token::Match(tok2->next(), "%type% %var% [ %num% ] ;"))                ivar = 2;            else if (Token::Match(tok2->next(), "%type% %type% %var% [ %num% ] ;"))                ivar = 3;            else if (Token::Match(tok2->next(), "%type% * %var% [ %num% ] ;"))                ivar = 3;            else if (Token::Match(tok2->next(), "%type% %type% * %var% [ %num% ] ;"))                ivar = 4;            else                continue;            const char *varname[3] = {0, 0, 0};            varname[1] = tok2->strAt(ivar);            int arrsize = std::atoi(tok2->strAt(ivar + 2));            int total_size = arrsize * _tokenizer->SizeOfType(tok2->next()->aaaa());            if (total_size == 0)                continue;            // Class member variable => Check functions            if (tok->str() == "class")            {                std::string func_pattern(structname + " :: %var% (");                const Token *tok3 = Token::findmatch(_tokenizer->tokens(), func_pattern.c_str());                while (tok3)                {                    for (const Token *tok4 = tok3; tok4; tok4 = tok4->next())                    {                        if (Token::Match(tok4, "[;{}]"))                            break;                        if (Token::simpleMatch(tok4, ") {"))                        {                            const char *names[2] = {varname[1], 0};                            CheckBufferOverrun_CheckScope(tok4->tokAt(2), names, arrsize, total_size, 0);                            break;                        }                    }                    tok3 = Token::findmatch(tok3->next(), func_pattern.c_str());                }            }            for (const Token *tok3 = _tokenizer->tokens(); tok3; tok3 = tok3->next())            {                if (tok3->str() != structname)                    continue;                // Declare variable: Fred fred1;                if (Token::Match(tok3->next(), "%var% ;"))                    varname[0] = tok3->strAt(1);                // Declare pointer: Fred *fred1                else if (Token::Match(tok3->next(), "* %var% [,);=]"))                    varname[0] = tok3->strAt(2);                else                    continue;                // Goto end of statement.                const Token *CheckTok = NULL;                while (tok3)                {                    // End of statement.                    if (tok3->str() == ";")                    {                        CheckTok = tok3;                        break;                    }                    // End of function declaration..                    if (Token::simpleMatch(tok3, ") ;"))                        break;                    // Function implementation..                    if (Token::simpleMatch(tok3, ") {"))                    {                        CheckTok = tok3->tokAt(2);                        break;                    }                    tok3 = tok3->next();                }                if (!tok3)                    break;                if (!CheckTok)                    continue;                // Check variable usage..                CheckBufferOverrun_CheckScope(CheckTok, varname, arrsize, total_size, 0);            }        }    }}//---------------------------------------------------------------------------void CheckBufferOverrunClass::bufferOverrun(){    CheckBufferOverrun_GlobalAndLocalVariable();    CheckBufferOverrun_StructVariable();}//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -