//== 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/Analysis/AnalysisContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TypeTraits.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.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;
  ASTContext &ASTC;

  /// 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", ASTC)
          && 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), ASTC(AC->getASTContext()) {
  }

  // 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) {
  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", ASTC)) {
    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>();
}

