llvm-project/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

68 lines
2.9 KiB
C
Raw Normal View History

[clang-tidy] New checker for not null-terminated result caused by strlen(), size() or equal length Summary: New checker called bugprone-not-null-terminated-result. This checker finds function calls where it is possible to cause a not null-terminated result. Usually the proper length of a string is `strlen(src) + 1` or equal length of this expression, because the null terminator needs an extra space. Without the null terminator it can result in undefined behaviour when the string is read. The following and their respective `wchar_t` based functions are checked: `memcpy`, `memcpy_s`, `memchr`, `memmove`, `memmove_s`, `strerror_s`, `strncmp`, `strxfrm` The following is a real-world example where the programmer forgot to increase the passed third argument, which is `size_t length`. That is why the length of the allocated memory is not enough to hold the null terminator. ``` static char *stringCpy(const std::string &str) { char *result = reinterpret_cast<char *>(malloc(str.size())); memcpy(result, str.data(), str.size()); return result; } ``` In addition to issuing warnings, fix-it rewrites all the necessary code. It also tries to adjust the capacity of the destination array: ``` static char *stringCpy(const std::string &str) { char *result = reinterpret_cast<char *>(malloc(str.size() + 1)); strcpy(result, str.data()); return result; } ``` Note: It cannot guarantee to rewrite every of the path-sensitive memory allocations. Reviewed By: JonasToth, aaron.ballman, whisperity, alexfh Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D45050 llvm-svn: 374707
2019-10-13 16:28:27 +08:00
//===--- NotNullTerminatedResultCheck.h - clang-tidy ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOT_NULL_TERMINATED_RESULT_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOT_NULL_TERMINATED_RESULT_H
#include "../ClangTidyCheck.h"
[clang-tidy] New checker for not null-terminated result caused by strlen(), size() or equal length Summary: New checker called bugprone-not-null-terminated-result. This checker finds function calls where it is possible to cause a not null-terminated result. Usually the proper length of a string is `strlen(src) + 1` or equal length of this expression, because the null terminator needs an extra space. Without the null terminator it can result in undefined behaviour when the string is read. The following and their respective `wchar_t` based functions are checked: `memcpy`, `memcpy_s`, `memchr`, `memmove`, `memmove_s`, `strerror_s`, `strncmp`, `strxfrm` The following is a real-world example where the programmer forgot to increase the passed third argument, which is `size_t length`. That is why the length of the allocated memory is not enough to hold the null terminator. ``` static char *stringCpy(const std::string &str) { char *result = reinterpret_cast<char *>(malloc(str.size())); memcpy(result, str.data(), str.size()); return result; } ``` In addition to issuing warnings, fix-it rewrites all the necessary code. It also tries to adjust the capacity of the destination array: ``` static char *stringCpy(const std::string &str) { char *result = reinterpret_cast<char *>(malloc(str.size() + 1)); strcpy(result, str.data()); return result; } ``` Note: It cannot guarantee to rewrite every of the path-sensitive memory allocations. Reviewed By: JonasToth, aaron.ballman, whisperity, alexfh Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D45050 llvm-svn: 374707
2019-10-13 16:28:27 +08:00
namespace clang {
namespace tidy {
namespace bugprone {
/// Finds function calls where it is possible to cause a not null-terminated
/// result. Usually the proper length of a string is 'strlen(src) + 1' or
/// equal length of this expression, because the null terminator needs an extra
/// space. Without the null terminator it can result in undefined behaviour
/// when the string is read.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-not-null-terminated-result.html
class NotNullTerminatedResultCheck : public ClangTidyCheck {
public:
NotNullTerminatedResultCheck(StringRef Name, ClangTidyContext *Context);
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
private:
// If non-zero it is specifying if the target environment is considered to
// implement '_s' suffixed memory and string handler functions which are safer
// than older version (e.g. 'memcpy_s()'). The default value is '1'.
const bool WantToUseSafeFunctions;
[clang-tidy] New checker for not null-terminated result caused by strlen(), size() or equal length Summary: New checker called bugprone-not-null-terminated-result. This checker finds function calls where it is possible to cause a not null-terminated result. Usually the proper length of a string is `strlen(src) + 1` or equal length of this expression, because the null terminator needs an extra space. Without the null terminator it can result in undefined behaviour when the string is read. The following and their respective `wchar_t` based functions are checked: `memcpy`, `memcpy_s`, `memchr`, `memmove`, `memmove_s`, `strerror_s`, `strncmp`, `strxfrm` The following is a real-world example where the programmer forgot to increase the passed third argument, which is `size_t length`. That is why the length of the allocated memory is not enough to hold the null terminator. ``` static char *stringCpy(const std::string &str) { char *result = reinterpret_cast<char *>(malloc(str.size())); memcpy(result, str.data(), str.size()); return result; } ``` In addition to issuing warnings, fix-it rewrites all the necessary code. It also tries to adjust the capacity of the destination array: ``` static char *stringCpy(const std::string &str) { char *result = reinterpret_cast<char *>(malloc(str.size() + 1)); strcpy(result, str.data()); return result; } ``` Note: It cannot guarantee to rewrite every of the path-sensitive memory allocations. Reviewed By: JonasToth, aaron.ballman, whisperity, alexfh Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D45050 llvm-svn: 374707
2019-10-13 16:28:27 +08:00
bool UseSafeFunctions = false;
void memoryHandlerFunctionFix(
StringRef Name, const ast_matchers::MatchFinder::MatchResult &Result);
void memcpyFix(StringRef Name,
const ast_matchers::MatchFinder::MatchResult &Result,
DiagnosticBuilder &Diag);
void memcpy_sFix(StringRef Name,
const ast_matchers::MatchFinder::MatchResult &Result,
DiagnosticBuilder &Diag);
void memchrFix(StringRef Name,
const ast_matchers::MatchFinder::MatchResult &Result);
void memmoveFix(StringRef Name,
const ast_matchers::MatchFinder::MatchResult &Result,
DiagnosticBuilder &Diag);
void strerror_sFix(const ast_matchers::MatchFinder::MatchResult &Result);
void ncmpFix(StringRef Name,
const ast_matchers::MatchFinder::MatchResult &Result);
void xfrmFix(StringRef Name,
const ast_matchers::MatchFinder::MatchResult &Result);
};
} // namespace bugprone
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOT_NULL_TERMINATED_RESULT_H