10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
21 for (
size_t i = 0; i < Node.getLength(); ++i)
22 if (Node.getCodeUnit(i) ==
'\0')
28 void StringLiteralWithEmbeddedNulCheck::registerMatchers(MatchFinder *Finder) {
31 Finder->addMatcher(stringLiteral(containsNul()).bind(
"strlit"),
this);
34 if (!getLangOpts().CPlusPlus)
37 const auto StrLitWithNul =
38 ignoringParenImpCasts(stringLiteral(containsNul()).bind(
"truncated"));
41 const auto StringConstructorExpr = expr(anyOf(
42 cxxConstructExpr(argumentCountIs(1),
43 hasDeclaration(cxxMethodDecl(hasName(
"basic_string")))),
46 cxxConstructExpr(argumentCountIs(2),
47 hasDeclaration(cxxMethodDecl(hasName(
"basic_string"))),
48 hasArgument(1, cxxDefaultArgExpr()))));
52 Finder->addMatcher(traverse(TK_AsIs,
53 cxxConstructExpr(StringConstructorExpr, hasArgument(0, StrLitWithNul))),
57 Finder->addMatcher(cxxOperatorCallExpr(hasAnyArgument(StrLitWithNul)),
this);
60 void StringLiteralWithEmbeddedNulCheck::check(
61 const MatchFinder::MatchResult &Result) {
62 if (
const auto *SL = Result.Nodes.getNodeAs<StringLiteral>(
"strlit")) {
67 SL->getCodeUnit(
Offset + 1) ==
'x' &&
68 isDigit(SL->getCodeUnit(
Offset + 2)) &&
69 isDigit(SL->getCodeUnit(
Offset + 3))) {
70 diag(SL->getBeginLoc(),
"suspicious embedded NUL character");
76 if (
const auto *SL = Result.Nodes.getNodeAs<StringLiteral>(
"truncated")) {
77 diag(SL->getBeginLoc(),
78 "truncated string literal with embedded NUL character");