// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gn/escape.h"

#include <stddef.h>

#include <memory>

#include "base/compiler_specific.h"
#include "base/json/string_escape.h"
#include "base/logging.h"
#include "util/build_config.h"

namespace {

constexpr size_t kStackStringBufferSize = 1024;
#if defined(OS_WIN)
constexpr size_t kMaxEscapedCharsPerChar = 2;
#else
constexpr size_t kMaxEscapedCharsPerChar = 3;
#endif

// A "1" in this lookup table means that char is valid in the Posix shell.
// clang-format off
const char kShellValid[0x80] = {
// 00-1f: all are invalid
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// ' ' !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
//  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
//  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
//  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
//  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
//  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
// clang-format on

size_t EscapeStringToString_Space(const std::string_view& str,
                                  const EscapeOptions& options,
                                  char* dest,
                                  bool* needed_quoting) {
  size_t i = 0;
  for (const auto& elem : str) {
    if (elem == ' ')
      dest[i++] = '\\';
    dest[i++] = elem;
  }
  return i;
}

// Uses the stack if the space needed is small and the heap otherwise.
class StackOrHeapBuffer {
 public:
  explicit StackOrHeapBuffer(size_t buf_size) {
    if (UNLIKELY(buf_size > kStackStringBufferSize))
      heap_buf.reset(new char[buf_size]);
  }
  operator char*() { return heap_buf ? heap_buf.get() : stack_buf; }

 private:
  char stack_buf[kStackStringBufferSize];
  std::unique_ptr<char[]> heap_buf;
};

// Ninja's escaping rules are very simple. We always escape colons even
// though they're OK in many places, in case the resulting string is used on
// the left-hand-side of a rule.
inline bool ShouldEscapeCharForNinja(char ch) {
  return ch == '$' || ch == ' ' || ch == ':';
}

size_t EscapeStringToString_Ninja(const std::string_view& str,
                                  const EscapeOptions& options,
                                  char* dest,
                                  bool* needed_quoting) {
  size_t i = 0;
  for (const auto& elem : str) {
    if (ShouldEscapeCharForNinja(elem))
      dest[i++] = '$';
    dest[i++] = elem;
  }
  return i;
}

inline bool ShouldEscapeCharForCompilationDatabase(char ch) {
  return ch == '\\' || ch == '"';
}

size_t EscapeStringToString_CompilationDatabase(const std::string_view& str,
                                                const EscapeOptions& options,
                                                char* dest,
                                                bool* needed_quoting) {
  size_t i = 0;
  bool quote = false;
  for (const auto& elem : str) {
    if (static_cast<unsigned>(elem) >= 0x80 ||
        !kShellValid[static_cast<int>(elem)]) {
      quote = true;
      break;
    }
  }
  if (quote)
    dest[i++] = '"';

  for (const auto& elem : str) {
    if (ShouldEscapeCharForCompilationDatabase(elem))
      dest[i++] = '\\';
    dest[i++] = elem;
  }
  if (quote)
    dest[i++] = '"';
  return i;
}

size_t EscapeStringToString_Depfile(const std::string_view& str,
                                    const EscapeOptions& options,
                                    char* dest,
                                    bool* needed_quoting) {
  size_t i = 0;
  for (const auto& elem : str) {
    // Escape all characters that ninja depfile parser can recognize as escaped,
    // even if some of them can work without escaping.
    if (elem == ' ' || elem == '\\' || elem == '#' || elem == '*' ||
        elem == '[' || elem == '|' || elem == ']')
      dest[i++] = '\\';
    else if (elem == '$')  // Extra rule for $$
      dest[i++] = '$';
    dest[i++] = elem;
  }
  return i;
}

size_t EscapeStringToString_NinjaPreformatted(const std::string_view& str,
                                              char* dest) {
  // Only Ninja-escape $.
  size_t i = 0;
  for (const auto& elem : str) {
    if (elem == '$')
      dest[i++] = '$';
    dest[i++] = elem;
  }
  return i;
}

// Escape for CommandLineToArgvW and additionally escape Ninja characters.
//
// The basic algorithm is if the string doesn't contain any parse-affecting
// characters, don't do anything (other than the Ninja processing). If it does,
// quote the string, and backslash-escape all quotes and backslashes.
// See:
//   http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
//   http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
size_t EscapeStringToString_WindowsNinjaFork(const std::string_view& str,
                                             const EscapeOptions& options,
                                             char* dest,
                                             bool* needed_quoting) {
  // We assume we don't have any whitespace chars that aren't spaces.
  DCHECK(str.find_first_of("\r\n\v\t") == std::string::npos);

  size_t i = 0;
  if (str.find_first_of(" \"") == std::string::npos) {
    // Simple case, don't quote.
    return EscapeStringToString_Ninja(str, options, dest, needed_quoting);
  } else {
    if (!options.inhibit_quoting)
      dest[i++] = '"';

    for (size_t j = 0; j < str.size(); j++) {
      // Count backslashes in case they're followed by a quote.
      size_t backslash_count = 0;
      while (j < str.size() && str[j] == '\\') {
        j++;
        backslash_count++;
      }
      if (j == str.size()) {
        // Backslashes at end of string. Backslash-escape all of them since
        // they'll be followed by a quote.
        memset(dest + i, '\\', backslash_count * 2);
        i += backslash_count * 2;
      } else if (str[j] == '"') {
        // 0 or more backslashes followed by a quote. Backslash-escape the
        // backslashes, then backslash-escape the quote.
        memset(dest + i, '\\', backslash_count * 2 + 1);
        i += backslash_count * 2 + 1;
        dest[i++] = '"';
      } else {
        // Non-special Windows character, just escape for Ninja. Also, add any
        // backslashes we read previously, these are literals.
        memset(dest + i, '\\', backslash_count);
        i += backslash_count;
        if (ShouldEscapeCharForNinja(str[j]))
          dest[i++] = '$';
        dest[i++] = str[j];
      }
    }

    if (!options.inhibit_quoting)
      dest[i++] = '"';
    if (needed_quoting)
      *needed_quoting = true;
  }
  return i;
}

size_t EscapeStringToString_PosixNinjaFork(const std::string_view& str,
                                           const EscapeOptions& options,
                                           char* dest,
                                           bool* needed_quoting) {
  size_t i = 0;
  for (const auto& elem : str) {
    if (elem == '$' || elem == ' ') {
      // Space and $ are special to both Ninja and the shell. '$' escape for
      // Ninja, then backslash-escape for the shell.
      dest[i++] = '\\';
      dest[i++] = '$';
      dest[i++] = elem;
    } else if (elem == ':') {
      // Colon is the only other Ninja special char, which is not special to
      // the shell.
      dest[i++] = '$';
      dest[i++] = ':';
    } else if (static_cast<unsigned>(elem) >= 0x80 ||
               !kShellValid[static_cast<int>(elem)]) {
      // All other invalid shell chars get backslash-escaped.
      dest[i++] = '\\';
      dest[i++] = elem;
    } else {
      // Everything else is a literal.
      dest[i++] = elem;
    }
  }
  return i;
}

// Escapes |str| into |dest| and returns the number of characters written.
size_t EscapeStringToString(const std::string_view& str,
                            const EscapeOptions& options,
                            char* dest,
                            bool* needed_quoting) {
  switch (options.mode) {
    case ESCAPE_NONE:
      strncpy(dest, str.data(), str.size());
      return str.size();
    case ESCAPE_SPACE:
      return EscapeStringToString_Space(str, options, dest, needed_quoting);
    case ESCAPE_NINJA:
      return EscapeStringToString_Ninja(str, options, dest, needed_quoting);
    case ESCAPE_DEPFILE:
      return EscapeStringToString_Depfile(str, options, dest, needed_quoting);
    case ESCAPE_COMPILATION_DATABASE:
      return EscapeStringToString_CompilationDatabase(str, options, dest,
                                                      needed_quoting);
    case ESCAPE_NINJA_COMMAND:
      switch (options.platform) {
        case ESCAPE_PLATFORM_CURRENT:
#if defined(OS_WIN)
          return EscapeStringToString_WindowsNinjaFork(str, options, dest,
                                                       needed_quoting);
#else
          return EscapeStringToString_PosixNinjaFork(str, options, dest,
                                                     needed_quoting);
#endif
        case ESCAPE_PLATFORM_WIN:
          return EscapeStringToString_WindowsNinjaFork(str, options, dest,
                                                       needed_quoting);
        case ESCAPE_PLATFORM_POSIX:
          return EscapeStringToString_PosixNinjaFork(str, options, dest,
                                                     needed_quoting);
        default:
          NOTREACHED();
      }
    case ESCAPE_NINJA_PREFORMATTED_COMMAND:
      return EscapeStringToString_NinjaPreformatted(str, dest);
    default:
      NOTREACHED();
  }
  return 0;
}

}  // namespace

std::string EscapeString(const std::string_view& str,
                         const EscapeOptions& options,
                         bool* needed_quoting) {
  StackOrHeapBuffer dest(str.size() * kMaxEscapedCharsPerChar);
  return std::string(dest,
                     EscapeStringToString(str, options, dest, needed_quoting));
}

void EscapeStringToStream(std::ostream& out,
                          const std::string_view& str,
                          const EscapeOptions& options) {
  StackOrHeapBuffer dest(str.size() * kMaxEscapedCharsPerChar);
  out.write(dest, EscapeStringToString(str, options, dest, nullptr));
}

void EscapeJSONStringToStream(std::ostream& out,
                              const std::string_view& str,
                              const EscapeOptions& options) {
  std::string dest;
  bool needed_quoting = !options.inhibit_quoting;
  base::EscapeJSONString(str, needed_quoting, &dest);

  EscapeStringToStream(out, dest, options);
}
