//== 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;

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

