11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 22 for (
size_t i = 0; i < Node.getLength(); ++i)
23 if (Node.getCodeUnit(i) ==
'\0')
29 void StringLiteralWithEmbeddedNulCheck::registerMatchers(MatchFinder *Finder) {
32 Finder->addMatcher(stringLiteral(containsNul()).bind(
"strlit"),
this);
35 if (!getLangOpts().CPlusPlus)
38 const auto StrLitWithNul =
39 ignoringParenImpCasts(stringLiteral(containsNul()).bind(
"truncated"));
42 const auto StringConstructorExpr = expr(anyOf(
43 cxxConstructExpr(argumentCountIs(1),
44 hasDeclaration(cxxMethodDecl(hasName(
"basic_string")))),
47 cxxConstructExpr(argumentCountIs(2),
48 hasDeclaration(cxxMethodDecl(hasName(
"basic_string"))),
49 hasArgument(1, cxxDefaultArgExpr()))));
54 cxxConstructExpr(StringConstructorExpr, hasArgument(0, StrLitWithNul)),
58 Finder->addMatcher(cxxOperatorCallExpr(hasAnyArgument(StrLitWithNul)),
this);
61 void StringLiteralWithEmbeddedNulCheck::check(
62 const MatchFinder::MatchResult &Result) {
63 if (
const auto *SL = Result.Nodes.getNodeAs<StringLiteral>(
"strlit")) {
64 for (
size_t Offset = 0, Length = SL->getLength(); Offset < Length;
67 if (Offset + 3 < Length && SL->getCodeUnit(Offset) ==
'\0' &&
68 SL->getCodeUnit(Offset + 1) ==
'x' &&
69 isDigit(SL->getCodeUnit(Offset + 2)) &&
70 isDigit(SL->getCodeUnit(Offset + 3))) {
71 diag(SL->getLocStart(),
"suspicious embedded NUL character");
77 if (
const auto *SL = Result.Nodes.getNodeAs<StringLiteral>(
"truncated")) {
78 diag(SL->getLocStart(),
79 "truncated string literal with embedded NUL character");
AST_MATCHER(BinaryOperator, isAssignmentOperator)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//