Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: base/string_util.cc

Issue 174342: Fix a bug where we reused a va_list across multiple calls. (Closed)
Patch Set: comment Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/string_util.h" 5 #include "base/string_util.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <ctype.h> 9 #include <ctype.h>
10 #include <errno.h> 10 #include <errno.h>
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 // the va_list, the caller is expected to do that. 936 // the va_list, the caller is expected to do that.
937 template <class StringType> 937 template <class StringType>
938 static void StringAppendVT(StringType* dst, 938 static void StringAppendVT(StringType* dst,
939 const typename StringType::value_type* format, 939 const typename StringType::value_type* format,
940 va_list ap) { 940 va_list ap) {
941 // First try with a small fixed size buffer. 941 // First try with a small fixed size buffer.
942 // This buffer size should be kept in sync with StringUtilTest.GrowBoundary 942 // This buffer size should be kept in sync with StringUtilTest.GrowBoundary
943 // and StringUtilTest.StringPrintfBounds. 943 // and StringUtilTest.StringPrintfBounds.
944 typename StringType::value_type stack_buf[1024]; 944 typename StringType::value_type stack_buf[1024];
945 945
946 va_list backup_ap; 946 va_list ap_copy;
947 GG_VA_COPY(backup_ap, ap); 947 GG_VA_COPY(ap_copy, ap);
948 948
949 #if !defined(OS_WIN) 949 #if !defined(OS_WIN)
950 errno = 0; 950 errno = 0;
951 #endif 951 #endif
952 int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, backup_ap); 952 int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, ap_copy);
953 va_end(backup_ap); 953 va_end(ap_copy);
954 954
955 if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) { 955 if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) {
956 // It fit. 956 // It fit.
957 dst->append(stack_buf, result); 957 dst->append(stack_buf, result);
958 return; 958 return;
959 } 959 }
960 960
961 // Repeatedly increase buffer size until it fits. 961 // Repeatedly increase buffer size until it fits.
962 int mem_length = arraysize(stack_buf); 962 int mem_length = arraysize(stack_buf);
963 while (true) { 963 while (true) {
(...skipping 19 matching lines...) Expand all
983 if (mem_length > 32 * 1024 * 1024) { 983 if (mem_length > 32 * 1024 * 1024) {
984 // That should be plenty, don't try anything larger. This protects 984 // That should be plenty, don't try anything larger. This protects
985 // against huge allocations when using vsnprintfT implementations that 985 // against huge allocations when using vsnprintfT implementations that
986 // return -1 for reasons other than overflow without setting errno. 986 // return -1 for reasons other than overflow without setting errno.
987 DLOG(WARNING) << "Unable to printf the requested string due to size."; 987 DLOG(WARNING) << "Unable to printf the requested string due to size.";
988 return; 988 return;
989 } 989 }
990 990
991 std::vector<typename StringType::value_type> mem_buf(mem_length); 991 std::vector<typename StringType::value_type> mem_buf(mem_length);
992 992
993 // Restore the va_list before we use it again. 993 // NOTE: You can only use a va_list once. Since we're in a while loop, we
994 GG_VA_COPY(backup_ap, ap); 994 // need to make a new copy each time so we don't use up the original.
995 995 GG_VA_COPY(ap_copy, ap);
996 result = vsnprintfT(&mem_buf[0], mem_length, format, ap); 996 result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy);
Evan Martin 2009/08/24 20:28:50 (note for brett: aside from the variable rename, t
997 va_end(backup_ap); 997 va_end(ap_copy);
998 998
999 if ((result >= 0) && (result < mem_length)) { 999 if ((result >= 0) && (result < mem_length)) {
1000 // It fit. 1000 // It fit.
1001 dst->append(&mem_buf[0], result); 1001 dst->append(&mem_buf[0], result);
1002 return; 1002 return;
1003 } 1003 }
1004 } 1004 }
1005 } 1005 }
1006 1006
1007 namespace { 1007 namespace {
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 // Each input byte creates two output hex characters. 1665 // Each input byte creates two output hex characters.
1666 std::string ret(size * 2, '\0'); 1666 std::string ret(size * 2, '\0');
1667 1667
1668 for (size_t i = 0; i < size; ++i) { 1668 for (size_t i = 0; i < size; ++i) {
1669 char b = reinterpret_cast<const char*>(bytes)[i]; 1669 char b = reinterpret_cast<const char*>(bytes)[i];
1670 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; 1670 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf];
1671 ret[(i * 2) + 1] = kHexChars[b & 0xf]; 1671 ret[(i * 2) + 1] = kHexChars[b & 0xf];
1672 } 1672 }
1673 return ret; 1673 return ret;
1674 } 1674 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698