//== CStringSyntaxChecker.cpp - CoreFoundation containers API *- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// An AST checker that looks for common pitfalls when using C string APIs.
//  - Identifies erroneous patterns in the last argument to strncat - the number
//    of bytes to copy.
//
//===----------------------------------------------------------------------===//
#include "ClangSACheckers.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TypeTraits.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace ento;

namespace {
class WalkAST: public StmtVisitor<WalkAST> {
  BugReporter &BR;
  AnalysisDeclContext* AC;

  /// Check if two expressions refer to the same declaration.
  inline bool sameDecl(const Expr *A1, const Expr *A2) {
    if (const DeclRefExpr *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
      if (const DeclRefExpr *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
        return D1->getDecl() == D2->getDecl();
    return false;
  }

  /// Check if the expression E is a sizeof(WithArg).
  inline bool isSizeof(const Expr *E, const Expr *WithArg) {
    if (const UnaryExprOrTypeTraitExpr *UE =
    dyn_cast<UnaryExprOrTypeTraitExpr>(E))
      if (UE->getKind() == UETT_SizeOf)
        return sameDecl(UE->getArgumentExpr(), WithArg);
    return false;
  }

  /// Check if the expression E is a strlen(WithArg).
  inline bool isStrlen(const Expr *E, const Expr *WithArg) {
    if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
      const FunctionDecl *FD = CE->getDirectCallee();
      if (!FD)
        return false;
      return (CheckerContext::isCLibraryFunction(FD, "strlen") &&
              sameDecl(CE->getArg(0), WithArg));
    }
    return false;
  }

  /// Check if the expression is an integer literal with value 1.
  inline bool isOne(const Expr *E) {
    if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
      return (IL->getValue().isIntN(1));
    return false;
  }

  inline StringRef getPrintableName(const Expr *E) {
    if (const DeclRefExpr *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
      return D->getDecl()->getName();
    return StringRef();
  }

  /// Identify erroneous patterns in the last argument to strncat - the number
  /// of bytes to copy.
  bool containsBadStrncatPattern(const CallExpr *CE);

public:
  WalkAST(BugReporter &br, AnalysisDeclContext* ac) :
      BR(br), AC(ac) {
  }

  // Statement visitor methods.
  void VisitChildren(Stmt *S);
  void VisitStmt(Stmt *S) {
    VisitChildren(S);
  }
  void VisitCallExpr(CallExpr *CE);
};
} // end anonymous namespace

// The correct size argument should look like following:
//   strncat(dst, src, sizeof(dst) - strlen(dest) - 1);
// We look for the following anti-patterns:
//   - strncat(dst, src, sizeof(dst) - strlen(dst));
//   - strncat(dst, src, sizeof(dst) - 1);
//   - strncat(dst, src, sizeof(dst));
bool WalkAST::containsBadStrncatPattern(const CallExpr *CE) {
  if (CE->getNumArgs() != 3)
    return false;
  const Expr *DstArg = CE->getArg(0);
  const Expr *SrcArg = CE->getArg(1);
  const Expr *LenArg = CE->getArg(2);

  // Identify wrong size expressions, which are commonly used instead.
  if (const BinaryOperator *BE =
              dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
    // - sizeof(dst) - strlen(dst)
    if (BE->getOpcode() == BO_Sub) {
      const Expr *L = BE->getLHS();
      const Expr *R = BE->getRHS();
      if (isSizeof(L, DstArg) && isStrlen(R, DstArg))
        return true;

      // - sizeof(dst) - 1
      if (isSizeof(L, DstArg) && isOne(R->IgnoreParenCasts()))
        return true;
    }
  }
  // - sizeof(dst)
  if (isSizeof(LenArg, DstArg))
    return true;

  // - sizeof(src)
  if (isSizeof(LenArg, SrcArg))
    return true;
  return false;
}

void WalkAST::VisitCallExpr(CallExpr *CE) {
  const FunctionDecl *FD = CE->getDirectCallee();
  if (!FD)
    return;

  if (CheckerContext::isCLibraryFunction(FD, "strncat")) {
    if (containsBadStrncatPattern(CE)) {
      const Expr *DstArg = CE->getArg(0);
      const Expr *LenArg = CE->getArg(2);
      SourceRange R = LenArg->getSourceRange();
      PathDiagnosticLocation Loc =
        PathDiagnosticLocation::createBegin(LenArg, BR.getSourceManager(), AC);

      StringRef DstName = getPrintableName(DstArg);

      SmallString<256> S;
      llvm::raw_svector_ostream os(S);
      os << "Potential buffer overflow. ";
      if (!DstName.empty()) {
        os << "Replace with 'sizeof(" << DstName << ") "
              "- strlen(" << DstName <<") - 1'";
        os << " or u";
      } else
        os << "U";
      os << "se a safer 'strlcat' API";

      BR.EmitBasicReport(FD, "Anti-pattern in the argument", "C String API",
                         os.str(), Loc, &R, 1);
    }
  }

  // Recurse and check children.
  VisitChildren(CE);
}

void WalkAST::VisitChildren(Stmt *S) {
  for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I != E;
      ++I)
    if (Stmt *child = *I)
      Visit(child);
}

namespace {
class CStringSyntaxChecker: public Checker<check::ASTCodeBody> {
public:

  void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
      BugReporter &BR) const {
    WalkAST walker(BR, Mgr.getAnalysisDeclContext(D));
    walker.Visit(D->getBody());
  }
};
}

void ento::registerCStringSyntaxChecker(CheckerManager &mgr) {
  mgr.registerChecker<CStringSyntaxChecker>();
}

