security/sandbox/chromium/base/strings/stringprintf.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/chromium/base/strings/stringprintf.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,186 @@
     1.4 +// Copyright 2013 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#include "base/strings/stringprintf.h"
     1.9 +
    1.10 +#include <errno.h>
    1.11 +
    1.12 +#include "base/scoped_clear_errno.h"
    1.13 +#include "base/strings/string_util.h"
    1.14 +#include "base/strings/utf_string_conversions.h"
    1.15 +
    1.16 +namespace base {
    1.17 +
    1.18 +namespace {
    1.19 +
    1.20 +// Overloaded wrappers around vsnprintf and vswprintf. The buf_size parameter
    1.21 +// is the size of the buffer. These return the number of characters in the
    1.22 +// formatted string excluding the NUL terminator. If the buffer is not
    1.23 +// large enough to accommodate the formatted string without truncation, they
    1.24 +// return the number of characters that would be in the fully-formatted string
    1.25 +// (vsnprintf, and vswprintf on Windows), or -1 (vswprintf on POSIX platforms).
    1.26 +inline int vsnprintfT(char* buffer,
    1.27 +                      size_t buf_size,
    1.28 +                      const char* format,
    1.29 +                      va_list argptr) {
    1.30 +  return base::vsnprintf(buffer, buf_size, format, argptr);
    1.31 +}
    1.32 +
    1.33 +#if !defined(OS_ANDROID)
    1.34 +inline int vsnprintfT(wchar_t* buffer,
    1.35 +                      size_t buf_size,
    1.36 +                      const wchar_t* format,
    1.37 +                      va_list argptr) {
    1.38 +  return base::vswprintf(buffer, buf_size, format, argptr);
    1.39 +}
    1.40 +#endif
    1.41 +
    1.42 +// Templatized backend for StringPrintF/StringAppendF. This does not finalize
    1.43 +// the va_list, the caller is expected to do that.
    1.44 +template <class StringType>
    1.45 +static void StringAppendVT(StringType* dst,
    1.46 +                           const typename StringType::value_type* format,
    1.47 +                           va_list ap) {
    1.48 +  // First try with a small fixed size buffer.
    1.49 +  // This buffer size should be kept in sync with StringUtilTest.GrowBoundary
    1.50 +  // and StringUtilTest.StringPrintfBounds.
    1.51 +  typename StringType::value_type stack_buf[1024];
    1.52 +
    1.53 +  va_list ap_copy;
    1.54 +  GG_VA_COPY(ap_copy, ap);
    1.55 +
    1.56 +#if !defined(OS_WIN)
    1.57 +  ScopedClearErrno clear_errno;
    1.58 +#endif
    1.59 +  int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, ap_copy);
    1.60 +  va_end(ap_copy);
    1.61 +
    1.62 +  if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) {
    1.63 +    // It fit.
    1.64 +    dst->append(stack_buf, result);
    1.65 +    return;
    1.66 +  }
    1.67 +
    1.68 +  // Repeatedly increase buffer size until it fits.
    1.69 +  int mem_length = arraysize(stack_buf);
    1.70 +  while (true) {
    1.71 +    if (result < 0) {
    1.72 +#if !defined(OS_WIN)
    1.73 +      // On Windows, vsnprintfT always returns the number of characters in a
    1.74 +      // fully-formatted string, so if we reach this point, something else is
    1.75 +      // wrong and no amount of buffer-doubling is going to fix it.
    1.76 +      if (errno != 0 && errno != EOVERFLOW)
    1.77 +#endif
    1.78 +      {
    1.79 +        // If an error other than overflow occurred, it's never going to work.
    1.80 +        DLOG(WARNING) << "Unable to printf the requested string due to error.";
    1.81 +        return;
    1.82 +      }
    1.83 +      // Try doubling the buffer size.
    1.84 +      mem_length *= 2;
    1.85 +    } else {
    1.86 +      // We need exactly "result + 1" characters.
    1.87 +      mem_length = result + 1;
    1.88 +    }
    1.89 +
    1.90 +    if (mem_length > 32 * 1024 * 1024) {
    1.91 +      // That should be plenty, don't try anything larger.  This protects
    1.92 +      // against huge allocations when using vsnprintfT implementations that
    1.93 +      // return -1 for reasons other than overflow without setting errno.
    1.94 +      DLOG(WARNING) << "Unable to printf the requested string due to size.";
    1.95 +      return;
    1.96 +    }
    1.97 +
    1.98 +    std::vector<typename StringType::value_type> mem_buf(mem_length);
    1.99 +
   1.100 +    // NOTE: You can only use a va_list once.  Since we're in a while loop, we
   1.101 +    // need to make a new copy each time so we don't use up the original.
   1.102 +    GG_VA_COPY(ap_copy, ap);
   1.103 +    result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy);
   1.104 +    va_end(ap_copy);
   1.105 +
   1.106 +    if ((result >= 0) && (result < mem_length)) {
   1.107 +      // It fit.
   1.108 +      dst->append(&mem_buf[0], result);
   1.109 +      return;
   1.110 +    }
   1.111 +  }
   1.112 +}
   1.113 +
   1.114 +}  // namespace
   1.115 +
   1.116 +std::string StringPrintf(const char* format, ...) {
   1.117 +  va_list ap;
   1.118 +  va_start(ap, format);
   1.119 +  std::string result;
   1.120 +  StringAppendV(&result, format, ap);
   1.121 +  va_end(ap);
   1.122 +  return result;
   1.123 +}
   1.124 +
   1.125 +#if !defined(OS_ANDROID)
   1.126 +std::wstring StringPrintf(const wchar_t* format, ...) {
   1.127 +  va_list ap;
   1.128 +  va_start(ap, format);
   1.129 +  std::wstring result;
   1.130 +  StringAppendV(&result, format, ap);
   1.131 +  va_end(ap);
   1.132 +  return result;
   1.133 +}
   1.134 +#endif
   1.135 +
   1.136 +std::string StringPrintV(const char* format, va_list ap) {
   1.137 +  std::string result;
   1.138 +  StringAppendV(&result, format, ap);
   1.139 +  return result;
   1.140 +}
   1.141 +
   1.142 +const std::string& SStringPrintf(std::string* dst, const char* format, ...) {
   1.143 +  va_list ap;
   1.144 +  va_start(ap, format);
   1.145 +  dst->clear();
   1.146 +  StringAppendV(dst, format, ap);
   1.147 +  va_end(ap);
   1.148 +  return *dst;
   1.149 +}
   1.150 +
   1.151 +#if !defined(OS_ANDROID)
   1.152 +const std::wstring& SStringPrintf(std::wstring* dst,
   1.153 +                                  const wchar_t* format, ...) {
   1.154 +  va_list ap;
   1.155 +  va_start(ap, format);
   1.156 +  dst->clear();
   1.157 +  StringAppendV(dst, format, ap);
   1.158 +  va_end(ap);
   1.159 +  return *dst;
   1.160 +}
   1.161 +#endif
   1.162 +
   1.163 +void StringAppendF(std::string* dst, const char* format, ...) {
   1.164 +  va_list ap;
   1.165 +  va_start(ap, format);
   1.166 +  StringAppendV(dst, format, ap);
   1.167 +  va_end(ap);
   1.168 +}
   1.169 +
   1.170 +#if !defined(OS_ANDROID)
   1.171 +void StringAppendF(std::wstring* dst, const wchar_t* format, ...) {
   1.172 +  va_list ap;
   1.173 +  va_start(ap, format);
   1.174 +  StringAppendV(dst, format, ap);
   1.175 +  va_end(ap);
   1.176 +}
   1.177 +#endif
   1.178 +
   1.179 +void StringAppendV(std::string* dst, const char* format, va_list ap) {
   1.180 +  StringAppendVT(dst, format, ap);
   1.181 +}
   1.182 +
   1.183 +#if !defined(OS_ANDROID)
   1.184 +void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap) {
   1.185 +  StringAppendVT(dst, format, ap);
   1.186 +}
   1.187 +#endif
   1.188 +
   1.189 +}  // namespace base

mercurial