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

Side by Side Diff: base/strings/safe_sprintf.h

Issue 102993006: Remove C++11 specific version of SafeSNPrintf() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update unit test as well Created 7 years 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 | base/strings/safe_sprintf_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #ifndef BASE_STRINGS_SAFE_SPRINTF_H_ 5 #ifndef BASE_STRINGS_SAFE_SPRINTF_H_
6 #define BASE_STRINGS_SAFE_SPRINTF_H_ 6 #define BASE_STRINGS_SAFE_SPRINTF_H_
7 7
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 9
10 #include <stddef.h> 10 #include <stddef.h>
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 // This ensures that the caller can always add one to the signed return code 97 // This ensures that the caller can always add one to the signed return code
98 // in order to determine the amount of storage that needs to be allocated. 98 // in order to determine the amount of storage that needs to be allocated.
99 // 99 //
100 // While the code supports type checking and while it is generally very careful 100 // While the code supports type checking and while it is generally very careful
101 // to avoid printing incorrect values, it tends to be conservative in printing 101 // to avoid printing incorrect values, it tends to be conservative in printing
102 // as much as possible, even when given incorrect parameters. Typically, in 102 // as much as possible, even when given incorrect parameters. Typically, in
103 // case of an error, the format string will not be expanded. (i.e. something 103 // case of an error, the format string will not be expanded. (i.e. something
104 // like SafeSPrintf(buf, "%p %d", 1, 2) results in "%p 2"). See above for 104 // like SafeSPrintf(buf, "%p %d", 1, 2) results in "%p 2"). See above for
105 // the use of RAW_CHECK() in debug builds, though. 105 // the use of RAW_CHECK() in debug builds, though.
106 // 106 //
107 // The pre-C++11 version cannot handle more than ten arguments.
108 //
109 // Basic example: 107 // Basic example:
110 // char buf[20]; 108 // char buf[20];
111 // base::strings::SafeSPrintf(buf, "The answer: %2d", 42); 109 // base::strings::SafeSPrintf(buf, "The answer: %2d", 42);
112 // 110 //
113 // Example with dynamically sized buffer (async-signal-safe). This code won't 111 // Example with dynamically sized buffer (async-signal-safe). This code won't
114 // work on Visual studio, as it requires dynamically allocating arrays on the 112 // work on Visual studio, as it requires dynamically allocating arrays on the
115 // stack. Consider picking a smaller value for |kMaxSize| if stack size is 113 // stack. Consider picking a smaller value for |kMaxSize| if stack size is
116 // limited and known. On the other hand, if the parameters to SafeSNPrintf() 114 // limited and known. On the other hand, if the parameters to SafeSNPrintf()
117 // are trusted and not controllable by the user, you can consider eliminating 115 // are trusted and not controllable by the user, you can consider eliminating
118 // the check for |kMaxSize| altogether. The current value of SSIZE_MAX is 116 // the check for |kMaxSize| altogether. The current value of SSIZE_MAX is
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 #if !defined(NDEBUG) 181 #if !defined(NDEBUG)
184 // In debug builds, allow unit tests to artificially lower the kSSizeMax 182 // In debug builds, allow unit tests to artificially lower the kSSizeMax
185 // constant that is used as a hard upper-bound for all buffers. In normal 183 // constant that is used as a hard upper-bound for all buffers. In normal
186 // use, this constant should always be std::numeric_limits<ssize_t>::max(). 184 // use, this constant should always be std::numeric_limits<ssize_t>::max().
187 BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max); 185 BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max);
188 BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest(); 186 BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest();
189 #endif 187 #endif
190 188
191 } // namespace internal 189 } // namespace internal
192 190
193 #if __cplusplus >= 201103 // C++11
194
195 template<typename... Args>
196 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args... args) {
197 // Use Arg() object to record type information and then copy arguments to an
198 // array to make it easier to iterate over them.
199 const internal::Arg arg_array[] = { args... };
200 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
201 }
202
203 template<size_t N, typename... Args>
204 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, Args... args) {
205 // Use Arg() object to record type information and then copy arguments to an
206 // array to make it easier to iterate over them.
207 const internal::Arg arg_array[] = { args... };
208 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
209 }
210
211 #else // Pre-C++11
212
213 // TODO(markus): C++11 has a much more concise and readable solution for 191 // TODO(markus): C++11 has a much more concise and readable solution for
214 // expressing what we are doing here. Delete the fall-back code for older 192 // expressing what we are doing here.
215 // compilers as soon as we have fully switched to C++11.
216 193
217 template<class T0, class T1, class T2, class T3, class T4, 194 template<class T0, class T1, class T2, class T3, class T4,
218 class T5, class T6, class T7, class T8, class T9> 195 class T5, class T6, class T7, class T8, class T9>
219 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, 196 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
220 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, 197 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
221 T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { 198 T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) {
222 // Use Arg() object to record type information and then copy arguments to an 199 // Use Arg() object to record type information and then copy arguments to an
223 // array to make it easier to iterate over them. 200 // array to make it easier to iterate over them.
224 const internal::Arg arg_array[] = { 201 const internal::Arg arg_array[] = {
225 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 202 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); 396 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
420 } 397 }
421 398
422 template<size_t N, class T0> 399 template<size_t N, class T0>
423 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0) { 400 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0) {
424 // Use Arg() object to record type information and then copy arguments to an 401 // Use Arg() object to record type information and then copy arguments to an
425 // array to make it easier to iterate over them. 402 // array to make it easier to iterate over them.
426 const internal::Arg arg_array[] = { arg0 }; 403 const internal::Arg arg_array[] = { arg0 };
427 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); 404 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
428 } 405 }
429 #endif
430 406
431 // Fast-path when we don't actually need to substitute any arguments. 407 // Fast-path when we don't actually need to substitute any arguments.
432 BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt); 408 BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt);
433 template<size_t N> 409 template<size_t N>
434 inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) { 410 inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) {
435 return SafeSNPrintf(buf, N, fmt); 411 return SafeSNPrintf(buf, N, fmt);
436 } 412 }
437 413
438 } // namespace strings 414 } // namespace strings
439 } // namespace base 415 } // namespace base
440 416
441 #endif // BASE_STRINGS_SAFE_SPRINTF_H_ 417 #endif // BASE_STRINGS_SAFE_SPRINTF_H_
OLDNEW
« no previous file with comments | « no previous file | base/strings/safe_sprintf_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698