Cppcheck
checkstring.h
Go to the documentation of this file.
1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2024 Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 //---------------------------------------------------------------------------
21 #ifndef checkstringH
22 #define checkstringH
23 //---------------------------------------------------------------------------
24 
25 #include "check.h"
26 #include "config.h"
27 #include "tokenize.h"
28 
29 #include <string>
30 
31 class ErrorLogger;
32 class Settings;
33 class Token;
34 
35 /// @addtogroup Checks
36 /// @{
37 
38 
39 /** @brief Detect misusage of C-style strings and related standard functions */
40 
41 class CPPCHECKLIB CheckString : public Check {
42 public:
43  /** @brief This constructor is used when registering the CheckClass */
44  CheckString() : Check(myName()) {}
45 
46 private:
47  /** @brief This constructor is used when running checks. */
48  CheckString(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
49  : Check(myName(), tokenizer, settings, errorLogger) {}
50 
51  /** @brief Run checks against the normal token list */
52  void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override {
53  CheckString checkString(&tokenizer, &tokenizer.getSettings(), errorLogger);
54 
55  // Checks
56  checkString.strPlusChar();
57  checkString.checkSuspiciousStringCompare();
58  checkString.stringLiteralWrite();
59  checkString.overlappingStrcmp();
60  checkString.checkIncorrectStringCompare();
61  checkString.sprintfOverlappingData();
63  }
64 
65  /** @brief undefined behaviour, writing string literal */
66  void stringLiteralWrite();
67 
68  /** @brief str plus char (unusual pointer arithmetic) */
69  void strPlusChar();
70 
71  /** @brief %Check for using bad usage of strncmp and substr */
72  void checkIncorrectStringCompare();
73 
74  /** @brief %Check for comparison of a string literal with a char* variable */
75  void checkSuspiciousStringCompare();
76 
77  /** @brief %Check for suspicious code that compares string literals for equality */
78  void checkAlwaysTrueOrFalseStringCompare();
79 
80  /** @brief %Check for overlapping strcmp() */
81  void overlappingStrcmp();
82 
83  /** @brief %Check for overlapping source and destination passed to sprintf() */
84  void sprintfOverlappingData();
85 
86  void stringLiteralWriteError(const Token *tok, const Token *strValue);
87  void sprintfOverlappingDataError(const Token *funcTok, const Token *tok, const std::string &varname);
88  void strPlusCharError(const Token *tok);
89  void incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string);
90  void incorrectStringBooleanError(const Token *tok, const std::string& string);
91  void alwaysTrueFalseStringCompareError(const Token *tok, const std::string& str1, const std::string& str2);
92  void alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2);
93  void suspiciousStringCompareError(const Token* tok, const std::string& var, bool isLong);
94  void suspiciousStringCompareError_char(const Token* tok, const std::string& var);
95  void overlappingStrcmpError(const Token* eq0, const Token *ne0);
96 
97  void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
98  CheckString c(nullptr, settings, errorLogger);
99  c.stringLiteralWriteError(nullptr, nullptr);
100  c.sprintfOverlappingDataError(nullptr, nullptr, "varname");
101  c.strPlusCharError(nullptr);
102  c.incorrectStringCompareError(nullptr, "substr", "\"Hello World\"");
103  c.suspiciousStringCompareError(nullptr, "foo", false);
104  c.suspiciousStringCompareError_char(nullptr, "foo");
105  c.incorrectStringBooleanError(nullptr, "\"Hello World\"");
106  c.incorrectStringBooleanError(nullptr, "\'x\'");
107  c.alwaysTrueFalseStringCompareError(nullptr, "str1", "str2");
108  c.alwaysTrueStringVariableCompareError(nullptr, "varname1", "varname2");
109  c.overlappingStrcmpError(nullptr, nullptr);
110  }
111 
112  static std::string myName() {
113  return "String";
114  }
115 
116  std::string classInfo() const override {
117  return "Detect misusage of C-style strings:\n"
118  "- overlapping buffers passed to sprintf as source and destination\n"
119  "- incorrect length arguments for 'substr' and 'strncmp'\n"
120  "- suspicious condition (runtime comparison of string literals)\n"
121  "- suspicious condition (string/char literals as boolean)\n"
122  "- suspicious comparison of a string literal with a char\\* variable\n"
123  "- suspicious comparison of '\\0' with a char\\* variable\n"
124  "- overlapping strcmp() expression\n";
125  }
126 };
127 /// @}
128 //---------------------------------------------------------------------------
129 #endif // checkstringH
Detect misusage of C-style strings and related standard functions.
Definition: checkstring.h:41
void checkSuspiciousStringCompare()
Check for comparison of a string literal with a char* variable
void checkIncorrectStringCompare()
Check for using bad usage of strncmp and substr
void suspiciousStringCompareError(const Token *tok, const std::string &var, bool isLong)
void incorrectStringBooleanError(const Token *tok, const std::string &string)
void overlappingStrcmp()
Check for overlapping strcmp()
void incorrectStringCompareError(const Token *tok, const std::string &func, const std::string &string)
static std::string myName()
Definition: checkstring.h:112
void strPlusCharError(const Token *tok)
void suspiciousStringCompareError_char(const Token *tok, const std::string &var)
CheckString()
This constructor is used when registering the CheckClass.
Definition: checkstring.h:44
std::string classInfo() const override
get information about this class, used to generate documentation
Definition: checkstring.h:116
void sprintfOverlappingData()
Check for overlapping source and destination passed to sprintf()
void stringLiteralWriteError(const Token *tok, const Token *strValue)
Definition: checkstring.cpp:74
void alwaysTrueStringVariableCompareError(const Token *tok, const std::string &str1, const std::string &str2)
CheckString(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
This constructor is used when running checks.
Definition: checkstring.h:48
void overlappingStrcmpError(const Token *eq0, const Token *ne0)
void stringLiteralWrite()
undefined behaviour, writing string literal
Definition: checkstring.cpp:55
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override
get error messages
Definition: checkstring.h:97
void strPlusChar()
str plus char (unusual pointer arithmetic)
void alwaysTrueFalseStringCompareError(const Token *tok, const std::string &str1, const std::string &str2)
void sprintfOverlappingDataError(const Token *funcTok, const Token *tok, const std::string &varname)
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override
Run checks against the normal token list.
Definition: checkstring.h:52
void checkAlwaysTrueOrFalseStringCompare()
Check for suspicious code that compares string literals for equality
Definition: checkstring.cpp:97
Interface class that cppcheck uses to communicate with the checks.
Definition: check.h:59
This is an interface, which the class responsible of error logging should implement.
Definition: errorlogger.h:214
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
The token list that the TokenList generates is a linked-list of this class.
Definition: token.h:150
The main purpose is to tokenize the source code.
Definition: tokenize.h:46
const Settings & getSettings() const
Definition: tokenize.h:615
#define CPPCHECKLIB
Definition: config.h:35