From 03f3ee62a0d9a7e38f1dfcbefae872cd08990dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 12 Jul 2009 19:18:38 +0200 Subject: [PATCH] cleanup: removed deprecated files. security checking and errmsg --- Makefile | 14 +- src/checksecurity.cpp | 108 ---------------- src/checksecurity.h | 75 ----------- test/testsecurity.cpp | 102 --------------- tools/dmake.cpp | 4 +- tools/errmsg.cpp | 290 ------------------------------------------ 6 files changed, 2 insertions(+), 591 deletions(-) delete mode 100644 src/checksecurity.cpp delete mode 100644 src/checksecurity.h delete mode 100644 test/testsecurity.cpp delete mode 100644 tools/errmsg.cpp diff --git a/Makefile b/Makefile index 24a42f793..a156bd553 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,6 @@ OBJECTS = src/checkautovariables.o \ src/checkheaders.o \ src/checkmemoryleak.o \ src/checkother.o \ - src/checksecurity.o \ src/checkstl.o \ src/checkunusedfunctions.o \ src/cppcheck.o \ @@ -43,7 +42,6 @@ TESTOBJ = test/testautovariables.o \ test/testpreprocessor.o \ test/testredundantif.o \ test/testrunner.o \ - test/testsecurity.o \ test/testsimplifytokens.o \ test/teststl.o \ test/testsuite.o \ @@ -59,7 +57,6 @@ TESTOBJ = test/testautovariables.o \ src/checkheaders.o \ src/checkmemoryleak.o \ src/checkother.o \ - src/checksecurity.o \ src/checkstl.o \ src/checkunusedfunctions.o \ src/cppcheck.o \ @@ -87,10 +84,7 @@ testrunner: $(TESTOBJ) test: all ./testrunner -tools: tools/errmsg tools/dmake - -tools/errmsg: tools/errmsg.cpp - $(CXX) $(CXXFLAGS) -o tools/errmsg tools/errmsg.cpp $(LDFLAGS) +tools: tools/dmake tools/dmake: tools/dmake.cpp src/filelister.cpp src/filelister.h $(CXX) $(CXXFLAGS) -o tools/dmake tools/dmake.cpp src/filelister.cpp $(LDFLAGS) @@ -126,9 +120,6 @@ src/checkmemoryleak.o: src/checkmemoryleak.cpp src/checkmemoryleak.h src/check.h src/checkother.o: src/checkother.cpp src/checkother.h src/check.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h src/mathlib.h $(CXX) $(CXXFLAGS) -c -o src/checkother.o src/checkother.cpp -src/checksecurity.o: src/checksecurity.cpp src/checksecurity.h src/check.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h - $(CXX) $(CXXFLAGS) -c -o src/checksecurity.o src/checksecurity.cpp - src/checkstl.o: src/checkstl.cpp src/checkstl.h src/check.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h $(CXX) $(CXXFLAGS) -c -o src/checkstl.o src/checkstl.cpp @@ -216,9 +207,6 @@ test/testredundantif.o: test/testredundantif.cpp src/tokenize.h src/settings.h s test/testrunner.o: test/testrunner.cpp test/testsuite.h src/errorlogger.h src/settings.h $(CXX) $(CXXFLAGS) -c -o test/testrunner.o test/testrunner.cpp -test/testsecurity.o: test/testsecurity.cpp src/tokenize.h src/settings.h src/errorlogger.h src/token.h src/checksecurity.h src/check.h test/testsuite.h - $(CXX) $(CXXFLAGS) -c -o test/testsecurity.o test/testsecurity.cpp - test/testsimplifytokens.o: test/testsimplifytokens.cpp test/testsuite.h src/errorlogger.h src/settings.h src/tokenize.h src/token.h $(CXX) $(CXXFLAGS) -c -o test/testsimplifytokens.o test/testsimplifytokens.cpp diff --git a/src/checksecurity.cpp b/src/checksecurity.cpp deleted file mode 100644 index a2f20c639..000000000 --- a/src/checksecurity.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see tokens(); - while (tok) - { - unsigned int varId = 0; - - // Search for a variable declaration - while (tok) - { - if (Token::Match(tok, "int %var% ;")) - { - varId = tok->next()->varId(); - break; - } - tok = tok->next(); - } - - if (!tok) - break; - - // Skip ahead a little with tok.. - tok = tok->tokAt(2); - - if (!tok) - break; - - // Now take a look at the variable usage.. - if (varId == 0) - continue; - - // Search for bad input.. - for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) - { - if (Token::Match(tok2, "cin >> %varid%", varId)) - unvalidatedInput(tok2); - if (Token::Match(tok2, "fscanf ( %var% , %str% , %varid%", varId)) - unvalidatedInput(tok2); - if (Token::Match(tok2, "scanf ( %str% , %varid%", varId)) - unvalidatedInput(tok2); - } - } -} - - -/** - * Read data from Form/GUI - * Todo: This function must be more customizable to be usable - */ -void CheckSecurity::gui() -{ - // input control classes whose values are insecure.. - const char *inputclass[] = {"TEdit", 0}; - - // functions that parse value without validating it.. - const std::string dangerousfunc("atoi|atof|strtol|strtoul"); - - for (unsigned int i = 0; inputclass[i]; ++i) - { - const std::string classname(inputclass[i]); - - for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) - { - // Declaration.. - if (Token::Match(tok, (classname + " * %var% ;|=").c_str())) - { - // Variable name.. - const std::string varname(tok->strAt(2)); - - // Getting the value.. - const Token *tok2 = Token::findmatch(tok, (dangerousfunc + " ( " + varname + " .").c_str()); - if (tok2) - unvalidatedInput(tok2); - } - } - } -} - - -void CheckSecurity::unvalidatedInput(const Token *tok) -{ - reportError(tok, "security", "unvalidatedInput", "Unvalidated input"); -} - diff --git a/src/checksecurity.h b/src/checksecurity.h deleted file mode 100644 index 2b5bf83c4..000000000 --- a/src/checksecurity.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - -extern std::ostringstream errout; - -class TestSecurity : public TestFixture -{ -public: - TestSecurity() : TestFixture("TestSecurity") - { } - -private: - - void run() - { - TEST_CASE(stdin1); - TEST_CASE(gui); - } - - void check(const char code[]) - { - // Tokenize.. - Tokenizer tokenizer; - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); - tokenizer.simplifyTokenList(); - - // Clear the error buffer.. - errout.str(""); - - // Check char variable usage.. - CheckSecurity checkSecurity(&tokenizer, 0, this); - checkSecurity.readnum(); - } - - - void stdin1() - { - check("void foo()\n" - "{\n" - " int i;\n" - " std::cin >> i;\n" - "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (security) Unvalidated input\n", errout.str()); - } - - - - - - void checkGui(const char code[]) - { - // Tokenize.. - Tokenizer tokenizer; - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); - tokenizer.simplifyTokenList(); - - // Clear the error buffer.. - errout.str(""); - - // Check char variable usage.. - CheckSecurity checkSecurity(&tokenizer, 0, this); - checkSecurity.gui(); - } - - - void gui() - { - // Reading the value of a textbox and converting it into an int without any validation.. - checkGui("void onok()\n" - "{\n" - " TEdit *editAbc;\n" - " abc = atoi(editAbc->Text.c_str());\n" - "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (security) Unvalidated input\n", errout.str()); - } -}; - -REGISTER_TEST(TestSecurity) diff --git a/tools/dmake.cpp b/tools/dmake.cpp index a4d5b0243..b2b67c200 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -105,9 +105,7 @@ int main() fout << "\t$(CXX) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LDFLAGS)\n\n"; fout << "test:\tall\n"; fout << "\t./testrunner\n\n"; - fout << "tools:\ttools/errmsg\ttools/dmake\n\n"; - fout << "tools/errmsg:\ttools/errmsg.cpp\n"; - fout << "\t$(CXX) $(CXXFLAGS) -o tools/errmsg tools/errmsg.cpp $(LDFLAGS)\n\n"; + fout << "tools:\ttools/dmake\n\n"; fout << "tools/dmake:\ttools/dmake.cpp\tsrc/filelister.cpp\tsrc/filelister.h\n"; fout << "\t$(CXX) $(CXXFLAGS) -o tools/dmake tools/dmake.cpp src/filelister.cpp $(LDFLAGS)\n\n"; fout << "clean:\n"; diff --git a/tools/errmsg.cpp b/tools/errmsg.cpp deleted file mode 100644 index e38daf549..000000000 --- a/tools/errmsg.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see -#include -#include -#include - -class Message -{ -public: - enum Settings {error, all, style, style_all, security, never}; - - Message(std::string funcname, Settings settings, std::string msg); - Message(std::string funcname, Settings settings, std::string msg, std::string par1); - Message(std::string funcname, Settings settings, std::string msg, std::string par1, std::string par2); - Message(std::string funcname, Settings settings, std::string msg, std::string par1, std::string par2, std::string details); - - void generateCode(std::ostream &ostr) const; - - void generateDoc(std::ostream &ostr, Settings i) const; - - std::string stringifySettings(bool text) const; - -private: - std::string _funcname; - std::string _msg; - std::string _par1; - std::string _par2; - Settings _settings; - std::string _details; - - std::string msg(bool code) const; -}; - - - - -int main() -{ - // Error messages.. - std::list err; - - // Generic error message - err.push_back(Message("genericError", Message::error, "%1", "msg")); - - // checkbufferoverrun.cpp - err.push_back(Message("arrayIndexOutOfBounds", Message::all, "Array index out of bounds")); - err.push_back(Message("bufferOverrun", Message::all, "Buffer overrun")); - err.push_back(Message("strncatUsage", Message::all, "Dangerous usage of strncat, possible buffer overrun")); - err.push_back(Message("outOfBounds", Message::error, "%1 is out of bounds", "what")); - err.push_back(Message("stlOutOfBounds", Message::error, "%1 is out of bounds", "what")); - - // checkclass.cpp.. - err.push_back(Message("noConstructor", Message::style, "The class '%1' has no constructor", "classname")); - err.push_back(Message("uninitVar", Message::style, "Member variable not initialized in the constructor '%1::%2'", "classname", "varname")); - err.push_back(Message("unusedPrivateFunction", Message::style, "Unused private function '%1::%2'", "classname", "funcname")); - err.push_back(Message("memsetClass", Message::error, "Using '%1' on class", "memfunc")); - err.push_back(Message("memsetStruct", Message::error, "Using '%1' on struct that contains a 'std::%2'", "memfunc", "classname")); - err.push_back(Message("operatorEq", Message::style, "'operator=' should return something")); - err.push_back(Message("virtualDestructor", Message::error, "Class %1 which is inherited by class %2 does not have a virtual destructor", "Base", "Derived")); - - // checkfunctionusage.cpp.. - err.push_back(Message("unusedFunction", Message::style_all, "[%1]: The function '%2' is never used", "filename", "funcname")); - - // checkmemoryleak.cpp.. - err.push_back(Message("mismatchAllocDealloc", Message::error, "Mismatching allocation and deallocation: %1", "varname")); - err.push_back(Message("memleak", Message::error, "Memory leak: %1", "varname")); - err.push_back(Message("memleakall", Message::all, "Memory leak: %1", "varname")); - err.push_back(Message("resourceLeak", Message::error, "Resource leak: %1", "varname")); - err.push_back(Message("deallocDealloc", Message::error, "Deallocating a deallocated pointer: %1", "varname")); - err.push_back(Message("deallocuse", Message::error, "Using '%1' after it is deallocated / released", "varname")); - err.push_back(Message("mismatchSize", Message::error, "The given size %1 is mismatching", "sz")); - - // checkother.cpp.. - err.push_back(Message("cstyleCast", Message::style, "C-style pointer casting")); - err.push_back(Message("redundantIfDelete0", Message::style, "Redundant condition. It is safe to deallocate a NULL pointer")); - err.push_back(Message("redundantIfRemove", Message::style, "Redundant condition. The remove function in the STL will not do anything if element doesn't exist")); - err.push_back(Message("dangerousUsageStrtol", Message::error, "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36")); - err.push_back(Message("ifNoAction", Message::style, "Found redundant if condition - 'if (condition);'")); - err.push_back(Message("sprintfOverlappingData", Message::error, "Overlapping data buffer %1", "varname", "", - " -- If copying takes place between objects that overlap as a result of a\n" - " call to sprintf() or snprintf(), the results are undefined.\n" - " http://www.opengroup.org/onlinepubs/000095399/functions/printf.html")); - err.push_back(Message("udivError", Message::error, "Unsigned division. The result will be wrong.")); - err.push_back(Message("udivWarning", Message::style_all, "Warning: Division with signed and unsigned operators")); - err.push_back(Message("unusedStructMember", Message::style, "struct or union member '%1::%2' is never used", "structname", "varname")); - err.push_back(Message("passedByValue", Message::style, "Function parameter '%1' is passed by value. It could be passed by reference instead.", "parname")); - err.push_back(Message("constStatement", Message::style, "Redundant code: Found a statement that begins with %1 constant", "type")); - err.push_back(Message("charArrayIndex", Message::style, "Warning - using char variable as array index")); - err.push_back(Message("charBitOp", Message::style, "Warning - using char variable in bit operation")); - err.push_back(Message("variableScope", Message::never, "The scope of the variable %1 can be limited", "varname")); - err.push_back(Message("conditionAlwaysTrueFalse", Message::style, "Condition is always %1", "truefalse")); - err.push_back(Message("strPlusChar", Message::error, "Unusual pointer arithmetic")); - err.push_back(Message("returnLocalVariable", Message::error, "Returning pointer to local array variable")); - - // checkdangerousfunctions.cpp.. - err.push_back(Message("dangerousFunctionmktemp", Message::style, "Found 'mktemp'. You should use 'mkstemp' instead")); - err.push_back(Message("dangerousFunctiongets", Message::style, "Found 'gets'. You should use 'fgets' instead")); - err.push_back(Message("dangerousFunctionscanf", Message::style, "Found 'scanf'. You should use 'fgets' instead")); - - // checkstl.cpp.. - err.push_back(Message("iteratorUsage", Message::error, "Same iterator is used with both %1 and %2", "container1", "container2")); - err.push_back(Message("erase", Message::error, "Dangerous usage of erase")); - err.push_back(Message("pushback", Message::error, "After push_back or push_front, the iterator '%1' may be invalid", "iterator_name")); - - - // checkvalidate.cpp - err.push_back(Message("unvalidatedInput", Message::security, "Unvalidated input")); - - - // Generate documentation.. - std::cout << "Generate doc.." << std::endl; - const unsigned int NUMSUITE = 5; - static const char * const suite[NUMSUITE] = { "error", "all", "style", "all + style", "security" }; - for (unsigned int i = 0; i < NUMSUITE; ++i) - { - const Message::Settings settings[NUMSUITE] = { Message::error, Message::all, Message::style, Message::style_all, Message::security }; - std::cout << " =" << suite[i] << "=" << std::endl; - for (std::list::const_iterator it = err.begin(); it != err.end(); ++it) - it->generateDoc(std::cout, settings[i]); - } - std::cout << std::endl; - - return 0; -} - - - - - -Message::Message(std::string funcname, Settings settings, std::string msg) - : _funcname(funcname), _msg(msg), _par1(""), _par2(""), _settings(settings), _details("") -{ } - -Message::Message(std::string funcname, Settings settings, std::string msg, std::string par1) - : _funcname(funcname), _msg(msg), _par1(par1), _par2(""), _settings(settings), _details("") -{ } - -Message::Message(std::string funcname, Settings settings, std::string msg, std::string par1, std::string par2) - : _funcname(funcname), _msg(msg), _par1(par1), _par2(par2), _settings(settings), _details("") -{ } - -Message::Message(std::string funcname, Settings settings, std::string msg, std::string par1, std::string par2, std::string details) - : _funcname(funcname), _msg(msg), _par1(par1), _par2(par2), _settings(settings), _details(details) -{ } - -std::string Message::msg(bool code) const -{ - const char *str = code ? "\"" : ""; - std::string ret(str + _msg + str); - - if (! _par1.empty()) - { - std::string::size_type pos = 0; - while ((pos = ret.find("%1", pos)) != std::string::npos) - { - ret.erase(pos, 2); - if (code) - ret.insert(pos, "\" + " + _par1 + " + \""); - else - ret.insert(pos, _par1); - } - } - - if (! _par2.empty()) - { - std::string::size_type pos = 0; - while ((pos = ret.find("%2", pos)) != std::string::npos) - { - ret.erase(pos, 2); - if (code) - ret.insert(pos, "\" + " + _par2 + " + \""); - else - ret.insert(pos, _par2); - } - } - - return ret; -} - -void Message::generateCode(std::ostream &ostr) const -{ - bool loc = bool(_msg.substr(0, 4) != "[%1]"); - - // Error message.. - ostr << " void " << _funcname << "("; - if (loc) - { - ostr << "const Tokenizer *tokenizer, "; - - if (_funcname == "mismatchAllocDealloc" || - _funcname == "arrayIndexOutOfBounds") - ostr << "const std::list &Location"; - else - ostr << "const Token *Location"; - } - /* - if (_details.size()) - ostr << ", const Settings &settings"; - */ - if (! _par1.empty()) - ostr << (loc ? ", " : "") << "const std::string &" << _par1; - if (! _par2.empty()) - ostr << ", const std::string &" << _par2; - ostr << ")\n"; - ostr << " {\n"; - ostr << " _writemsg("; - if (loc) - ostr << "tokenizer, Location, \"" << stringifySettings(true) << "\", "; - ostr << msg(true) << ", \"" << _funcname << "\");\n"; - /* - ostr << " return "; - if (loc) - ostr << "msg1(tokenizer, Location) + "; - ostr << " std::string(\"(" << stringifySettings(true) << ") \") + "; - ostr << msg(true); - if (_details.empty()) - ostr << ";\n"; - else - { - ostr << " + std::string(settings._verbose ? \"\\n"; - for (std::string::size_type pos = 0; pos < _details.length(); ++pos) - { - if (_details[pos] == '\n') - ostr << "\\n"; - else - ostr << _details[pos]; - } - ostr << "\" : \"\");\n"; - } - */ - ostr << " }\n"; - - // Settings.. - ostr << " static bool " << _funcname << "("; - if (_settings != error && _settings != never) - ostr << "const Settings &s"; - ostr << ")" << std::endl; - ostr << " {\n"; - ostr << " return " << stringifySettings(false) << ";\n"; - ostr << " }\n\n"; -} - -void Message::generateDoc(std::ostream &ostr, Message::Settings i) const -{ - if (_settings == i) - { - ostr << " " << msg(false) << std::endl; - } -} - - -std::string Message::stringifySettings(bool text) const -{ - switch (_settings) - { - case error: - return text ? "error" : "true"; - case all: - return text ? "all" : "s._showAll"; - case style: - return text ? "style" : "s._checkCodingStyle"; - case style_all: - return text ? "all style" : "s._checkCodingStyle || s._showAll"; - case security: - return text ? "security" : "s._security"; - case never: - return text ? "never" : "false"; - } - return ""; -} - - -