summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2018-02-28 23:30:29 +0000
committerAlexander Kornienko <alexfh@google.com>2018-02-28 23:30:29 +0000
commitcb6d32034514bcdd152a95684ed309149f06070d (patch)
tree5f755c450fb834f7a0b1837eacf42743efed5cb1 /clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
parentff9595a002d48a4470f0518c26920fab39e2f62c (diff)
downloadbcm5719-llvm-cb6d32034514bcdd152a95684ed309149f06070d.tar.gz
bcm5719-llvm-cb6d32034514bcdd152a95684ed309149f06070d.zip
Rename more checks from misc- to bugprone-.
Summary: clang-tidy/rename_check.py {misc,bugprone}-string-integer-assignment clang-tidy/rename_check.py {misc,bugprone}-string-literal-with-embedded-nul clang-tidy/rename_check.py {misc,bugprone}-suspicious-enum-usage clang-tidy/rename_check.py {misc,bugprone}-suspicious-missing-comma Reviewers: hokein, sammccall, aaron.ballman Subscribers: klimek, cfe-commits, mgorny Differential Revision: https://reviews.llvm.org/D43868 llvm-svn: 326384
Diffstat (limited to 'clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
new file mode 100644
index 00000000000..eaa610fc64e
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
@@ -0,0 +1,85 @@
+//===--- StringLiteralWithEmbeddedNulCheck.cpp - clang-tidy----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StringLiteralWithEmbeddedNulCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+namespace {
+AST_MATCHER(StringLiteral, containsNul) {
+ for (size_t i = 0; i < Node.getLength(); ++i)
+ if (Node.getCodeUnit(i) == '\0')
+ return true;
+ return false;
+}
+} // namespace
+
+void StringLiteralWithEmbeddedNulCheck::registerMatchers(MatchFinder *Finder) {
+ // Match a string that contains embedded NUL character. Extra-checks are
+ // applied in |check| to find incorectly escaped characters.
+ Finder->addMatcher(stringLiteral(containsNul()).bind("strlit"), this);
+
+ // The remaining checks only apply to C++.
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ const auto StrLitWithNul =
+ ignoringParenImpCasts(stringLiteral(containsNul()).bind("truncated"));
+
+ // Match string constructor.
+ const auto StringConstructorExpr = expr(anyOf(
+ cxxConstructExpr(argumentCountIs(1),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
+ // If present, the second argument is the alloc object which must not
+ // be present explicitly.
+ cxxConstructExpr(argumentCountIs(2),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
+ hasArgument(1, cxxDefaultArgExpr()))));
+
+ // Detect passing a suspicious string literal to a string constructor.
+ // example: std::string str = "abc\0def";
+ Finder->addMatcher(
+ cxxConstructExpr(StringConstructorExpr, hasArgument(0, StrLitWithNul)),
+ this);
+
+ // Detect passing a suspicious string literal through an overloaded operator.
+ Finder->addMatcher(cxxOperatorCallExpr(hasAnyArgument(StrLitWithNul)), this);
+}
+
+void StringLiteralWithEmbeddedNulCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ if (const auto *SL = Result.Nodes.getNodeAs<StringLiteral>("strlit")) {
+ for (size_t Offset = 0, Length = SL->getLength(); Offset < Length;
+ ++Offset) {
+ // Find a sequence of character like "\0x12".
+ if (Offset + 3 < Length && SL->getCodeUnit(Offset) == '\0' &&
+ SL->getCodeUnit(Offset + 1) == 'x' &&
+ isDigit(SL->getCodeUnit(Offset + 2)) &&
+ isDigit(SL->getCodeUnit(Offset + 3))) {
+ diag(SL->getLocStart(), "suspicious embedded NUL character");
+ return;
+ }
+ }
+ }
+
+ if (const auto *SL = Result.Nodes.getNodeAs<StringLiteral>("truncated")) {
+ diag(SL->getLocStart(),
+ "truncated string literal with embedded NUL character");
+ }
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
OpenPOWER on IntegriCloud