// Copyright 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 "base/strings/safe_sprintf.h"

#include <errno.h>
#include <string.h>

#include <limits>

#include "base/macros.h"
#include "build/build_config.h"

#if !defined(NDEBUG)
// In debug builds, we use RAW_CHECK() to print useful error messages, if
// SafeSPrintf() is called with broken arguments.
// As our contract promises that SafeSPrintf() can be called from any
// restricted run-time context, it is not actually safe to call logging
// functions from it; and we only ever do so for debug builds and hope for the
// best. We should _never_ call any logging function other than RAW_CHECK(),
// and we should _never_ include any logging code that is active in production
// builds. Most notably, we should not include these logging functions in
// unofficial release builds, even though those builds would otherwise have
// DCHECKS() enabled.
// In other words; please do not remove the #ifdef around this #include.
// Instead, in production builds we opt for returning a degraded result,
// whenever an error is encountered.
// E.g. The broken function call
//        SafeSPrintf("errno = %d (%x)", errno, strerror(errno))
//      will print something like
//        errno = 13, (%x)
//      instead of
//        errno = 13 (Access denied)
//      In most of the anticipated use cases, that's probably the preferred
//      behavior.
#include "base/logging.h"
#define DEBUG_CHECK RAW_CHECK
#else
#define DEBUG_CHECK(x) do { if (x) { } } while (0)
#endif

namespace base {
namespace strings {

// The code in this file is extremely careful to be async-signal-safe.
//
// Most obviously, we avoid calling any code that could dynamically allocate
// memory. Doing so would almost certainly result in bugs and dead-locks.
// We also avoid calling any other STL functions that could have unintended
// side-effects involving memory allocation or access to other shared
// resources.
//
// But on top of that, we also avoid calling other library functions, as many
// of them have the side-effect of calling getenv() (in order to deal with
// localization) or accessing errno. The latter sounds benign, but there are
// several execution contexts where it isn't even possible to safely read let
// alone write errno.
//
// The stated design goal of the SafeSPrintf() function is that it can be
// called from any context that can safely call C or C++ code (i.e. anything
// that doesn't require assembly code).
//
// For a brief overview of some but not all of the issues with async-signal-
// safety, refer to:
// http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html

namespace {
const size_t kSSizeMaxConst = ((size_t)(ssize_t)-1) >> 1;

const char kUpCaseHexDigits[]   = "0123456789ABCDEF";
const char kDownCaseHexDigits[] = "0123456789abcdef";
}

#if defined(NDEBUG)
// We would like to define kSSizeMax as std::numeric_limits<ssize_t>::max(),
// but C++ doesn't allow us to do that for constants. Instead, we have to
// use careful casting and shifting. We later use a static_assert to
// verify that this worked correctly.
namespace {
const size_t kSSizeMax = kSSizeMaxConst;
}
#else  // defined(NDEBUG)
// For efficiency, we really need kSSizeMax to be a constant. But for unit
// tests, it should be adjustable. This allows us to verify edge cases without
// having to fill the entire available address space. As a compromise, we make
// kSSizeMax adjustable in debug builds, and then only compile that particular
// part of the unit test in debug builds.
namespace {
static size_t kSSizeMax = kSSizeMaxConst;
}

namespace internal {
void SetSafeSPrintfSSizeMaxForTest(size_t max) {
  kSSizeMax = max;
}

size_t GetSafeSPrintfSSizeMaxForTest() {
  return kSSizeMax;
}
}
#endif  // defined(NDEBUG)

namespace {
class Buffer {
 public:
  // |buffer| is caller-allocated storage that SafeSPrintf() writes to. It
  // has |size| bytes of writable storage. It is the caller's responsibility
  // to ensure that the buffer is at least one byte in size, so that it fits
  // the trailing NUL that will be added by the destructor. The buffer also
  // must be smaller or equal to kSSizeMax in size.
  Buffer(char* buffer, size_t size)
      : buffer_(buffer),
        size_(size - 1),  // Account for trailing NUL byte
        count_(0) {
// MSVS2013's standard library doesn't mark max() as constexpr yet. cl.exe
// supports static_cast but doesn't really implement constexpr yet so it doesn't
// complain, but clang does.
#if __cplusplus >= 201103 && !(defined(__clang__) && defined(OS_WIN))
    static_assert(kSSizeMaxConst ==
                      static_cast<size_t>(std::numeric_limits<ssize_t>::max()),
                  "kSSizeMaxConst should be the max value of an ssize_t");
#endif
    DEBUG_CHECK(size > 0);
    DEBUG_CHECK(size <= kSSizeMax);
  }

  ~Buffer() {
    // The code calling the constructor guaranteed that there was enough space
    // to store a trailing NUL -- and in debug builds, we are actually
    // verifying this with DEBUG_CHECK()s in the constructor. So, we can
    // always unconditionally write the NUL byte in the destructor.  We do not
    // need to adjust the count_, as SafeSPrintf() copies snprintf() in not
    // including the NUL byte in its return code.
    *GetInsertionPoint() = '\000';
  }

  // Returns true, iff the buffer is filled all the way to |kSSizeMax-1|. The
  // caller can now stop adding more data, as GetCount() has reached its
  // maximum possible value.
  inline bool OutOfAddressableSpace() const {
    return count_ == static_cast<size_t>(kSSizeMax - 1);
  }

  // Returns the number of bytes that would have been emitted to |buffer_|
  // if it was sized sufficiently large. This number can be larger than
  // |size_|, if the caller provided an insufficiently large output buffer.
  // But it will never be bigger than |kSSizeMax-1|.
  inline ssize_t GetCount() const {
    DEBUG_CHECK(count_ < kSSizeMax);
    return static_cast<ssize_t>(count_);
  }

  // Emits one |ch| character into the |buffer_| and updates the |count_| of
  // characters that are currently supposed to be in the buffer.
  // Returns "false", iff the buffer was already full.
  // N.B. |count_| increases even if no characters have been written. This is
  // needed so that GetCount() can return the number of bytes that should
  // have been allocated for the |buffer_|.
  inline bool Out(char ch) {
    if (size_ >= 1 && count_ < size_) {
      buffer_[count_] = ch;
      return IncrementCountByOne();
    }
    // |count_| still needs to be updated, even if the buffer has been
    // filled completely. This allows SafeSPrintf() to return the number of
    // bytes that should have been emitted.
    IncrementCountByOne();
    return false;
  }

  // Inserts |padding|-|len| bytes worth of padding into the |buffer_|.
  // |count_| will also be incremented by the number of bytes that were meant
  // to be emitted. The |pad| character is typically either a ' ' space
  // or a '0' zero, but other non-NUL values are legal.
  // Returns "false", iff the the |buffer_| filled up (i.e. |count_|
  // overflowed |size_|) at any time during padding.
  inline bool Pad(char pad, size_t padding, size_t len) {
    DEBUG_CHECK(pad);
    DEBUG_CHECK(padding <= kSSizeMax);
    for (; padding > len; --padding) {
      if (!Out(pad)) {
        if (--padding) {
          IncrementCount(padding-len);
        }
        return false;
      }
    }
    return true;
  }

  // POSIX doesn't define any async-signal-safe function for converting
  // an integer to ASCII. Define our own version.
  //
  // This also gives us the ability to make the function a little more
  // powerful and have it deal with |padding|, with truncation, and with
  // predicting the length of the untruncated output.
  //
  // IToASCII() converts an integer |i| to ASCII.
  //
  // Unlike similar functions in the standard C library, it never appends a
  // NUL character. This is left for the caller to do.
  //
  // While the function signature takes a signed int64_t, the code decides at
  // run-time whether to treat the argument as signed (int64_t) or as unsigned
  // (uint64_t) based on the value of |sign|.
  //
  // It supports |base|s 2 through 16. Only a |base| of 10 is allowed to have
  // a |sign|. Otherwise, |i| is treated as unsigned.
  //
  // For bases larger than 10, |upcase| decides whether lower-case or upper-
  // case letters should be used to designate digits greater than 10.
  //
  // Padding can be done with either '0' zeros or ' ' spaces. Padding has to
  // be positive and will always be applied to the left of the output.
  //
  // Prepends a |prefix| to the number (e.g. "0x"). This prefix goes to
  // the left of |padding|, if |pad| is '0'; and to the right of |padding|
  // if |pad| is ' '.
  //
  // Returns "false", if the |buffer_| overflowed at any time.
  bool IToASCII(bool sign, bool upcase, int64_t i, int base,
                char pad, size_t padding, const char* prefix);

 private:
  // Increments |count_| by |inc| unless this would cause |count_| to
  // overflow |kSSizeMax-1|. Returns "false", iff an overflow was detected;
  // it then clamps |count_| to |kSSizeMax-1|.
  inline bool IncrementCount(size_t inc) {
    // "inc" is either 1 or a "padding" value. Padding is clamped at
    // run-time to at most kSSizeMax-1. So, we know that "inc" is always in
    // the range 1..kSSizeMax-1.
    // This allows us to compute "kSSizeMax - 1 - inc" without incurring any
    // integer overflows.
    DEBUG_CHECK(inc <= kSSizeMax - 1);
    if (count_ > kSSizeMax - 1 - inc) {
      count_ = kSSizeMax - 1;
      return false;
    } else {
      count_ += inc;
      return true;
    }
  }

  // Convenience method for the common case of incrementing |count_| by one.
  inline bool IncrementCountByOne() {
    return IncrementCount(1);
  }

  // Return the current insertion point into the buffer. This is typically
  // at |buffer_| + |count_|, but could be before that if truncation
  // happened. It always points to one byte past the last byte that was
  // successfully placed into the |buffer_|.
  inline char* GetInsertionPoint() const {
    size_t idx = count_;
    if (idx > size_) {
      idx = size_;
    }
    return buffer_ + idx;
  }

  // User-provided buffer that will receive the fully formatted output string.
  char* buffer_;

  // Number of bytes that are available in the buffer excluding the trailing
  // NUL byte that will be added by the destructor.
  const size_t size_;

  // Number of bytes that would have been emitted to the buffer, if the buffer
  // was sufficiently big. This number always excludes the trailing NUL byte
  // and it is guaranteed to never grow bigger than kSSizeMax-1.
  size_t count_;

  DISALLOW_COPY_AND_ASSIGN(Buffer);
};


bool Buffer::IToASCII(bool sign, bool upcase, int64_t i, int base,
                      char pad, size_t padding, const char* prefix) {
  // Sanity check for parameters. None of these should ever fail, but see
  // above for the rationale why we can't call CHECK().
  DEBUG_CHECK(base >= 2);
  DEBUG_CHECK(base <= 16);
  DEBUG_CHECK(!sign || base == 10);
  DEBUG_CHECK(pad == '0' || pad == ' ');
  DEBUG_CHECK(padding <= kSSizeMax);
  DEBUG_CHECK(!(sign && prefix && *prefix));

  // Handle negative numbers, if the caller indicated that |i| should be
  // treated as a signed number; otherwise treat |i| as unsigned (even if the
  // MSB is set!)
  // Details are tricky, because of limited data-types, but equivalent pseudo-
  // code would look like:
  //   if (sign && i < 0)
  //     prefix = "-";
  //   num = abs(i);
  int minint = 0;
  uint64_t num;
  if (sign && i < 0) {
    prefix = "-";

    // Turn our number positive.
    if (i == std::numeric_limits<int64_t>::min()) {
      // The most negative integer needs special treatment.
      minint = 1;
      num = static_cast<uint64_t>(-(i + 1));
    } else {
      // "Normal" negative numbers are easy.
      num = static_cast<uint64_t>(-i);
    }
  } else {
    num = static_cast<uint64_t>(i);
  }

  // If padding with '0' zero, emit the prefix or '-' character now. Otherwise,
  // make the prefix accessible in reverse order, so that we can later output
  // it right between padding and the number.
  // We cannot choose the easier approach of just reversing the number, as that
  // fails in situations where we need to truncate numbers that have padding
  // and/or prefixes.
  const char* reverse_prefix = NULL;
  if (prefix && *prefix) {
    if (pad == '0') {
      while (*prefix) {
        if (padding) {
          --padding;
        }
        Out(*prefix++);
      }
      prefix = NULL;
    } else {
      for (reverse_prefix = prefix; *reverse_prefix; ++reverse_prefix) {
      }
    }
  } else
    prefix = NULL;
  const size_t prefix_length = reverse_prefix - prefix;

  // Loop until we have converted the entire number. Output at least one
  // character (i.e. '0').
  size_t start = count_;
  size_t discarded = 0;
  bool started = false;
  do {
    // Make sure there is still enough space left in our output buffer.
    if (count_ >= size_) {
      if (start < size_) {
        // It is rare that we need to output a partial number. But if asked
        // to do so, we will still make sure we output the correct number of
        // leading digits.
        // Since we are generating the digits in reverse order, we actually
        // have to discard digits in the order that we have already emitted
        // them. This is essentially equivalent to:
        //   memmove(buffer_ + start, buffer_ + start + 1, size_ - start - 1)
        for (char* move = buffer_ + start, *end = buffer_ + size_ - 1;
             move < end;
             ++move) {
          *move = move[1];
        }
        ++discarded;
        --count_;
      } else if (count_ - size_ > 1) {
        // Need to increment either |count_| or |discarded| to make progress.
        // The latter is more efficient, as it eventually triggers fast
        // handling of padding. But we have to ensure we don't accidentally
        // change the overall state (i.e. switch the state-machine from
        // discarding to non-discarding). |count_| needs to always stay
        // bigger than |size_|.
        --count_;
        ++discarded;
      }
    }

    // Output the next digit and (if necessary) compensate for the most
    // negative integer needing special treatment. This works because,
    // no matter the bit width of the integer, the lowest-most decimal
    // integer always ends in 2, 4, 6, or 8.
    if (!num && started) {
      if (reverse_prefix > prefix) {
        Out(*--reverse_prefix);
      } else {
        Out(pad);
      }
    } else {
      started = true;
      Out((upcase ? kUpCaseHexDigits : kDownCaseHexDigits)[num%base + minint]);
    }

    minint = 0;
    num /= base;

    // Add padding, if requested.
    if (padding > 0) {
      --padding;

      // Performance optimization for when we are asked to output excessive
      // padding, but our output buffer is limited in size.  Even if we output
      // a 64bit number in binary, we would never write more than 64 plus
      // prefix non-padding characters. So, once this limit has been passed,
      // any further state change can be computed arithmetically; we know that
      // by this time, our entire final output consists of padding characters
      // that have all already been output.
      if (discarded > 8*sizeof(num) + prefix_length) {
        IncrementCount(padding);
        padding = 0;
      }
    }
  } while (num || padding || (reverse_prefix > prefix));

  // Conversion to ASCII actually resulted in the digits being in reverse
  // order. We can't easily generate them in forward order, as we can't tell
  // the number of characters needed until we are done converting.
  // So, now, we reverse the string (except for the possible '-' sign).
  char* front = buffer_ + start;
  char* back = GetInsertionPoint();
  while (--back > front) {
    char ch = *back;
    *back = *front;
    *front++ = ch;
  }

  IncrementCount(discarded);
  return !discarded;
}

}  // anonymous namespace

namespace internal {

ssize_t SafeSNPrintf(char* buf, size_t sz, const char* fmt, const Arg* args,
                     const size_t max_args) {
  // Make sure that at least one NUL byte can be written, and that the buffer
  // never overflows kSSizeMax. Not only does that use up most or all of the
  // address space, it also would result in a return code that cannot be
  // represented.
  if (static_cast<ssize_t>(sz) < 1) {
    return -1;
  } else if (sz > kSSizeMax) {
    sz = kSSizeMax;
  }

  // Iterate over format string and interpret '%' arguments as they are
  // encountered.
  Buffer buffer(buf, sz);
  size_t padding;
  char pad;
  for (unsigned int cur_arg = 0; *fmt && !buffer.OutOfAddressableSpace(); ) {
    if (*fmt++ == '%') {
      padding = 0;
      pad = ' ';
      char ch = *fmt++;
    format_character_found:
      switch (ch) {
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        // Found a width parameter. Convert to an integer value and store in
        // "padding". If the leading digit is a zero, change the padding
        // character from a space ' ' to a zero '0'.
        pad = ch == '0' ? '0' : ' ';
        for (;;) {
          // The maximum allowed padding fills all the available address
          // space and leaves just enough space to insert the trailing NUL.
          const size_t max_padding = kSSizeMax - 1;
          if (padding > max_padding/10 ||
              10*padding > max_padding - (ch - '0')) {
            DEBUG_CHECK(padding <= max_padding/10 &&
                        10*padding <= max_padding - (ch - '0'));
            // Integer overflow detected. Skip the rest of the width until
            // we find the format character, then do the normal error handling.
          padding_overflow:
            padding = max_padding;
            while ((ch = *fmt++) >= '0' && ch <= '9') {
            }
            if (cur_arg < max_args) {
              ++cur_arg;
            }
            goto fail_to_expand;
          }
          padding = 10*padding + ch - '0';
          if (padding > max_padding) {
            // This doesn't happen for "sane" values of kSSizeMax. But once
            // kSSizeMax gets smaller than about 10, our earlier range checks
            // are incomplete. Unittests do trigger this artificial corner
            // case.
            DEBUG_CHECK(padding <= max_padding);
            goto padding_overflow;
          }
          ch = *fmt++;
          if (ch < '0' || ch > '9') {
            // Reached the end of the width parameter. This is where the format
            // character is found.
            goto format_character_found;
          }
        }
        break;
      case 'c': {  // Output an ASCII character.
        // Check that there are arguments left to be inserted.
        if (cur_arg >= max_args) {
          DEBUG_CHECK(cur_arg < max_args);
          goto fail_to_expand;
        }

        // Check that the argument has the expected type.
        const Arg& arg = args[cur_arg++];
        if (arg.type != Arg::INT && arg.type != Arg::UINT) {
          DEBUG_CHECK(arg.type == Arg::INT || arg.type == Arg::UINT);
          goto fail_to_expand;
        }

        // Apply padding, if needed.
        buffer.Pad(' ', padding, 1);

        // Convert the argument to an ASCII character and output it.
        char as_char = static_cast<char>(arg.integer.i);
        if (!as_char) {
          goto end_of_output_buffer;
        }
        buffer.Out(as_char);
        break; }
      case 'd':    // Output a possibly signed decimal value.
      case 'o':    // Output an unsigned octal value.
      case 'x':    // Output an unsigned hexadecimal value.
      case 'X':
      case 'p': {  // Output a pointer value.
        // Check that there are arguments left to be inserted.
        if (cur_arg >= max_args) {
          DEBUG_CHECK(cur_arg < max_args);
          goto fail_to_expand;
        }

        const Arg& arg = args[cur_arg++];
        int64_t i;
        const char* prefix = NULL;
        if (ch != 'p') {
          // Check that the argument has the expected type.
          if (arg.type != Arg::INT && arg.type != Arg::UINT) {
            DEBUG_CHECK(arg.type == Arg::INT || arg.type == Arg::UINT);
            goto fail_to_expand;
          }
          i = arg.integer.i;

          if (ch != 'd') {
            // The Arg() constructor automatically performed sign expansion on
            // signed parameters. This is great when outputting a %d decimal
            // number, but can result in unexpected leading 0xFF bytes when
            // outputting a %x hexadecimal number. Mask bits, if necessary.
            // We have to do this here, instead of in the Arg() constructor, as
            // the Arg() constructor cannot tell whether we will output a %d
            // or a %x. Only the latter should experience masking.
            if (arg.integer.width < sizeof(int64_t)) {
              i &= (1LL << (8*arg.integer.width)) - 1;
            }
          }
        } else {
          // Pointer values require an actual pointer or a string.
          if (arg.type == Arg::POINTER) {
            i = reinterpret_cast<uintptr_t>(arg.ptr);
          } else if (arg.type == Arg::STRING) {
            i = reinterpret_cast<uintptr_t>(arg.str);
          } else if (arg.type == Arg::INT &&
                     arg.integer.width == sizeof(NULL) &&
                     arg.integer.i == 0) {  // Allow C++'s version of NULL
            i = 0;
          } else {
            DEBUG_CHECK(arg.type == Arg::POINTER || arg.type == Arg::STRING);
            goto fail_to_expand;
          }

          // Pointers always include the "0x" prefix.
          prefix = "0x";
        }

        // Use IToASCII() to convert to ASCII representation. For decimal
        // numbers, optionally print a sign. For hexadecimal numbers,
        // distinguish between upper and lower case. %p addresses are always
        // printed as upcase. Supports base 8, 10, and 16. Prints padding
        // and/or prefixes, if so requested.
        buffer.IToASCII(ch == 'd' && arg.type == Arg::INT,
                        ch != 'x', i,
                        ch == 'o' ? 8 : ch == 'd' ? 10 : 16,
                        pad, padding, prefix);
        break; }
      case 's': {
        // Check that there are arguments left to be inserted.
        if (cur_arg >= max_args) {
          DEBUG_CHECK(cur_arg < max_args);
          goto fail_to_expand;
        }

        // Check that the argument has the expected type.
        const Arg& arg = args[cur_arg++];
        const char *s;
        if (arg.type == Arg::STRING) {
          s = arg.str ? arg.str : "<NULL>";
        } else if (arg.type == Arg::INT && arg.integer.width == sizeof(NULL) &&
                   arg.integer.i == 0) {  // Allow C++'s version of NULL
          s = "<NULL>";
        } else {
          DEBUG_CHECK(arg.type == Arg::STRING);
          goto fail_to_expand;
        }

        // Apply padding, if needed. This requires us to first check the
        // length of the string that we are outputting.
        if (padding) {
          size_t len = 0;
          for (const char* src = s; *src++; ) {
            ++len;
          }
          buffer.Pad(' ', padding, len);
        }

        // Printing a string involves nothing more than copying it into the
        // output buffer and making sure we don't output more bytes than
        // available space; Out() takes care of doing that.
        for (const char* src = s; *src; ) {
          buffer.Out(*src++);
        }
        break; }
      case '%':
        // Quoted percent '%' character.
        goto copy_verbatim;
      fail_to_expand:
        // C++ gives us tools to do type checking -- something that snprintf()
        // could never really do. So, whenever we see arguments that don't
        // match up with the format string, we refuse to output them. But
        // since we have to be extremely conservative about being async-
        // signal-safe, we are limited in the type of error handling that we
        // can do in production builds (in debug builds we can use
        // DEBUG_CHECK() and hope for the best). So, all we do is pass the
        // format string unchanged. That should eventually get the user's
        // attention; and in the meantime, it hopefully doesn't lose too much
        // data.
      default:
        // Unknown or unsupported format character. Just copy verbatim to
        // output.
        buffer.Out('%');
        DEBUG_CHECK(ch);
        if (!ch) {
          goto end_of_format_string;
        }
        buffer.Out(ch);
        break;
      }
    } else {
  copy_verbatim:
    buffer.Out(fmt[-1]);
    }
  }
 end_of_format_string:
 end_of_output_buffer:
  return buffer.GetCount();
}

}  // namespace internal

ssize_t SafeSNPrintf(char* buf, size_t sz, const char* fmt) {
  // Make sure that at least one NUL byte can be written, and that the buffer
  // never overflows kSSizeMax. Not only does that use up most or all of the
  // address space, it also would result in a return code that cannot be
  // represented.
  if (static_cast<ssize_t>(sz) < 1) {
    return -1;
  } else if (sz > kSSizeMax) {
    sz = kSSizeMax;
  }

  Buffer buffer(buf, sz);

  // In the slow-path, we deal with errors by copying the contents of
  // "fmt" unexpanded. This means, if there are no arguments passed, the
  // SafeSPrintf() function always degenerates to a version of strncpy() that
  // de-duplicates '%' characters.
  const char* src = fmt;
  for (; *src; ++src) {
    buffer.Out(*src);
    DEBUG_CHECK(src[0] != '%' || src[1] == '%');
    if (src[0] == '%' && src[1] == '%') {
      ++src;
    }
  }
  return buffer.GetCount();
}

}  // namespace strings
}  // namespace base
