|
Cppcheck
|
00001 /* 00002 * Cppcheck - A tool for static C/C++ code analysis 00003 * Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team. 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 00020 //--------------------------------------------------------------------------- 00021 #ifndef CheckObsoleteFunctionsH 00022 #define CheckObsoleteFunctionsH 00023 //--------------------------------------------------------------------------- 00024 00025 #include "config.h" 00026 #include "check.h" 00027 #include <string> 00028 #include <map> 00029 00030 00031 /// @addtogroup Checks 00032 /// @{ 00033 00034 /** 00035 * @brief Using obsolete functions that are always insecure to use. 00036 */ 00037 00038 class CPPCHECKLIB CheckObsoleteFunctions : public Check { 00039 public: 00040 /** This constructor is used when registering the CheckObsoleteFunctions */ 00041 CheckObsoleteFunctions() : Check(myName()) { 00042 initObsoleteFunctions(); 00043 } 00044 00045 /** This constructor is used when running checks. */ 00046 CheckObsoleteFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) 00047 : Check(myName(), tokenizer, settings, errorLogger) { 00048 initObsoleteFunctions(); 00049 } 00050 00051 void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) { 00052 CheckObsoleteFunctions checkObsoleteFunctions(tokenizer, settings, errorLogger); 00053 checkObsoleteFunctions.obsoleteFunctions(); 00054 } 00055 00056 /** Check for obsolete functions */ 00057 void obsoleteFunctions(); 00058 00059 private: 00060 /* function name / error message */ 00061 std::map<std::string, std::string> _obsoleteStandardFunctions; 00062 std::map<std::string, std::string> _obsoletePosixFunctions; 00063 std::map<std::string, std::string> _obsoleteC99Functions; 00064 00065 /** init obsolete functions list ' */ 00066 void initObsoleteFunctions() { 00067 // Obsolete posix functions, which messages suggest only one alternative and doesn't contain additional information. 00068 const struct { 00069 const char* bad; 00070 const char* good; 00071 } posix_stdmsgs[] = { 00072 {"bsd_signal", "sigaction"}, 00073 {"gethostbyaddr", "getnameinfo"}, 00074 {"gethostbyname", "getaddrinfo"}, 00075 {"bcmp", "memcmp"}, 00076 {"bzero", "memset"}, 00077 {"ecvt", "sprintf"}, 00078 {"fcvt", "sprintf"}, 00079 {"gcvt", "sprintf"}, 00080 {"getwd", "getcwd"}, 00081 {"index", "strchr"}, // See #2334 (using the Qt Model/View function 'index') 00082 {"rindex", "strrchr"}, 00083 {"pthread_attr_getstackaddr", "pthread_attr_getstack"}, 00084 {"pthread_attr_setstackaddr", "pthread_attr_setstack"}, 00085 {"vfork", "fork"}, 00086 {"wcswcs", "wcsstr"}, 00087 {"rand_r", "rand"}, 00088 {"utime", "utimensat"}, 00089 {"asctime_r", "strftime"}, 00090 {"ctime_r", "strftime"} 00091 }; 00092 00093 for (std::size_t i = 0; i < (sizeof(posix_stdmsgs) / sizeof(*posix_stdmsgs)); ++i) { 00094 _obsoletePosixFunctions[posix_stdmsgs[i].bad] = "Obsolete function '" + std::string(posix_stdmsgs[i].bad) + "' called. It is recommended to use the function '" + posix_stdmsgs[i].good + "' instead."; 00095 } 00096 00097 _obsoletePosixFunctions["usleep"] = "Obsolete function 'usleep' called. It is recommended to use the 'nanosleep' or 'setitimer' function instead.\n" 00098 "The obsolete function 'usleep' is called. POSIX.1-2001 declares usleep() function obsolete and POSIX.1-2008 removes it. It is recommended that new applications use the 'nanosleep' or 'setitimer' function."; 00099 00100 _obsoletePosixFunctions["bcopy"] = "Obsolete function 'bcopy' called. It is recommended to use the 'memmove' or 'memcpy' function instead."; 00101 00102 _obsoletePosixFunctions["ftime"] = "Obsolete function 'ftime' called. It is recommended to use time(), gettimeofday() or clock_gettime() instead."; 00103 00104 _obsoletePosixFunctions["getcontext"] = "Obsolete function 'getcontext' called. Due to portability issues, applications are recommended to be rewritten to use POSIX threads."; 00105 _obsoletePosixFunctions["makecontext"] = "Obsolete function 'makecontext' called. Due to portability issues, applications are recommended to be rewritten to use POSIX threads."; 00106 _obsoletePosixFunctions["swapcontext"] = "Obsolete function 'swapcontext' called. Due to portability issues, applications are recommended to be rewritten to use POSIX threads."; 00107 00108 _obsoletePosixFunctions["scalbln"] = "Obsolete function 'scalb' called. It is recommended to use 'scalbln', 'scalblnf' or 'scalblnl' instead."; 00109 00110 _obsoletePosixFunctions["ualarm"] = "Obsolete function 'ualarm' called. It is recommended to use 'timer_create', 'timer_delete', 'timer_getoverrun', 'timer_gettime' or 'timer_settime' instead."; 00111 00112 _obsoletePosixFunctions["tmpnam"] = "Obsolete function 'tmpnam' called. It is recommended to use 'tmpfile', 'mkstemp' or 'mkdtemp' instead."; 00113 00114 _obsoletePosixFunctions["tmpnam_r"] = "Obsolete function 'tmpnam_r' called. It is recommended to use 'tmpfile', 'mkstemp' or 'mkdtemp' instead."; 00115 00116 _obsoleteStandardFunctions["gets"] = "Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead.\n" 00117 "The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun if the input data exceeds the size of the buffer. It is recommended to use the function 'fgets' instead."; 00118 _obsoleteC99Functions["alloca"] = "Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead.\n" 00119 "The obsolete function 'alloca' is called. In C99 and later it is recommended to use a variable length array or a dynamically allocated array instead. The function 'alloca' is dangerous for many reasons (http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice and http://linux.die.net/man/3/alloca)."; 00120 _obsoleteC99Functions["asctime"] = "Obsolete function 'asctime' called. It is recommended to use the function 'strftime' instead."; 00121 // ctime is obsolete - it's not threadsafe. but there is no good replacement. 00122 //_obsoleteC99Functions["ctime"] = "Obsolete function 'ctime' called. It is recommended to use the function 'strftime' instead."; 00123 } 00124 00125 void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { 00126 CheckObsoleteFunctions c(0, settings, errorLogger); 00127 00128 std::map<std::string,std::string>::const_iterator it(_obsoletePosixFunctions.begin()), itend(_obsoletePosixFunctions.end()); 00129 for (; it!=itend; ++it) { 00130 c.reportError(0, Severity::style, "obsoleteFunctions"+it->first, it->second); 00131 } 00132 } 00133 00134 static std::string myName() { 00135 return "Obsolete functions"; 00136 } 00137 00138 std::string classInfo() const { 00139 std::string info = "Warn if any of these obsolete functions are used:\n"; 00140 std::map<std::string,std::string>::const_iterator it(_obsoletePosixFunctions.begin()), itend(_obsoletePosixFunctions.end()); 00141 for (; it!=itend; ++it) { 00142 info += "* " + it->first + "\n"; 00143 } 00144 return info; 00145 } 00146 }; 00147 /// @} 00148 //--------------------------------------------------------------------------- 00149 #endif
1.7.6.1