//===-- SpecialCaseList.cpp - special case list for sanitizers ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is a utility class for instrumentation passes (like AddressSanitizer
// or ThreadSanitizer) to avoid instrumenting some functions or global
// variables, or to instrument some functions or global variables in a specific
// way, based on a user-supplied list.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/SpecialCaseList.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <string>
#include <system_error>
#include <utility>

#include <stdio.h>
namespace llvm {

bool SpecialCaseList::Matcher::insert(std::string Regexp,
                                      unsigned LineNumber,
                                      std::string &REError) {
  if (Regexp.empty()) {
    REError = "Supplied regexp was blank";
    return false;
  }

  if (Regex::isLiteralERE(Regexp)) {
    Strings[Regexp] = LineNumber;
    return true;
  }
  Trigrams.insert(Regexp);

  // Replace * with .*
  for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos;
       pos += strlen(".*")) {
    Regexp.replace(pos, strlen("*"), ".*");
  }

  Regexp = (Twine("^(") + StringRef(Regexp) + ")$").str();

  // Check that the regexp is valid.
  Regex CheckRE(Regexp);
  if (!CheckRE.isValid(REError))
    return false;

  RegExes.emplace_back(
      std::make_pair(std::make_unique<Regex>(std::move(CheckRE)), LineNumber));
  return true;
}

unsigned SpecialCaseList::Matcher::match(StringRef Query) const {
  auto It = Strings.find(Query);
  if (It != Strings.end())
    return It->second;
  if (Trigrams.isDefinitelyOut(Query))
    return false;
  for (auto& RegExKV : RegExes)
    if (RegExKV.first->match(Query))
      return RegExKV.second;
  return 0;
}

std::unique_ptr<SpecialCaseList>
SpecialCaseList::create(const std::vector<std::string> &Paths,
                        llvm::vfs::FileSystem &FS, std::string &Error) {
  std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
  if (SCL->createInternal(Paths, FS, Error))
    return SCL;
  return nullptr;
}

std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
                                                         std::string &Error) {
  std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
  if (SCL->createInternal(MB, Error))
    return SCL;
  return nullptr;
}

std::unique_ptr<SpecialCaseList>
SpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
                             llvm::vfs::FileSystem &FS) {
  std::string Error;
  if (auto SCL = create(Paths, FS, Error))
    return SCL;
  report_fatal_error(Error);
}

bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths,
                                     vfs::FileSystem &VFS, std::string &Error) {
  StringMap<size_t> Sections;
  for (const auto &Path : Paths) {
    ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
        VFS.getBufferForFile(Path);
    if (std::error_code EC = FileOrErr.getError()) {
      Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
      return false;
    }
    std::string ParseError;
    if (!parse(FileOrErr.get().get(), Sections, ParseError)) {
      Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
      return false;
    }
  }
  return true;
}

bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
                                     std::string &Error) {
  StringMap<size_t> Sections;
  if (!parse(MB, Sections, Error))
    return false;
  return true;
}

bool SpecialCaseList::parse(const MemoryBuffer *MB,
                            StringMap<size_t> &SectionsMap,
                            std::string &Error) {
  // Iterate through each line in the blacklist file.
  SmallVector<StringRef, 16> Lines;
  MB->getBuffer().split(Lines, '\n');

  unsigned LineNo = 1;
  StringRef Section = "*";

  for (auto I = Lines.begin(), E = Lines.end(); I != E; ++I, ++LineNo) {
    *I = I->trim();
    // Ignore empty lines and lines starting with "#"
    if (I->empty() || I->startswith("#"))
      continue;

    // Save section names
    if (I->startswith("[")) {
      if (!I->endswith("]")) {
        Error = (Twine("malformed section header on line ") + Twine(LineNo) +
                 ": " + *I).str();
        return false;
      }

      Section = I->slice(1, I->size() - 1);

      std::string REError;
      Regex CheckRE(Section);
      if (!CheckRE.isValid(REError)) {
        Error =
            (Twine("malformed regex for section ") + Section + ": '" + REError)
                .str();
        return false;
      }

      continue;
    }

    // Get our prefix and unparsed regexp.
    std::pair<StringRef, StringRef> SplitLine = I->split(":");
    StringRef Prefix = SplitLine.first;
    if (SplitLine.second.empty()) {
      // Missing ':' in the line.
      Error = (Twine("malformed line ") + Twine(LineNo) + ": '" +
               SplitLine.first + "'").str();
      return false;
    }

    std::pair<StringRef, StringRef> SplitRegexp = SplitLine.second.split("=");
    std::string Regexp = SplitRegexp.first;
    StringRef Category = SplitRegexp.second;

    // Create this section if it has not been seen before.
    if (SectionsMap.find(Section) == SectionsMap.end()) {
      std::unique_ptr<Matcher> M = std::make_unique<Matcher>();
      std::string REError;
      if (!M->insert(Section, LineNo, REError)) {
        Error = (Twine("malformed section ") + Section + ": '" + REError).str();
        return false;
      }

      SectionsMap[Section] = Sections.size();
      Sections.emplace_back(std::move(M));
    }

    auto &Entry = Sections[SectionsMap[Section]].Entries[Prefix][Category];
    std::string REError;
    if (!Entry.insert(std::move(Regexp), LineNo, REError)) {
      Error = (Twine("malformed regex in line ") + Twine(LineNo) + ": '" +
               SplitLine.second + "': " + REError).str();
      return false;
    }
  }
  return true;
}

SpecialCaseList::~SpecialCaseList() {}

bool SpecialCaseList::inSection(StringRef Section, StringRef Prefix,
                                StringRef Query, StringRef Category) const {
  return inSectionBlame(Section, Prefix, Query, Category);
}

unsigned SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix,
                                         StringRef Query,
                                         StringRef Category) const {
  for (auto &SectionIter : Sections)
    if (SectionIter.SectionMatcher->match(Section)) {
      unsigned Blame =
          inSectionBlame(SectionIter.Entries, Prefix, Query, Category);
      if (Blame)
        return Blame;
    }
  return 0;
}

unsigned SpecialCaseList::inSectionBlame(const SectionEntries &Entries,
                                         StringRef Prefix, StringRef Query,
                                         StringRef Category) const {
  SectionEntries::const_iterator I = Entries.find(Prefix);
  if (I == Entries.end()) return 0;
  StringMap<Matcher>::const_iterator II = I->second.find(Category);
  if (II == I->second.end()) return 0;

  return II->getValue().match(Query);
}

}  // namespace llvm
