OLD | NEW |
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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 #if !defined(NDEBUG) | 211 #if !defined(NDEBUG) |
212 // In debug builds, allow unit tests to artificially lower the kSSizeMax | 212 // In debug builds, allow unit tests to artificially lower the kSSizeMax |
213 // constant that is used as a hard upper-bound for all buffers. In normal | 213 // constant that is used as a hard upper-bound for all buffers. In normal |
214 // use, this constant should always be std::numeric_limits<ssize_t>::max(). | 214 // use, this constant should always be std::numeric_limits<ssize_t>::max(). |
215 BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max); | 215 BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max); |
216 BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest(); | 216 BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest(); |
217 #endif | 217 #endif |
218 | 218 |
219 } // namespace internal | 219 } // namespace internal |
220 | 220 |
221 // TODO(markus): C++11 has a much more concise and readable solution for | 221 template<typename... Args> |
222 // expressing what we are doing here. | 222 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args... args) { |
223 | |
224 template<class T0, class T1, class T2, class T3, class T4, | |
225 class T5, class T6, class T7, class T8, class T9> | |
226 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
227 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
228 T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { | |
229 // Use Arg() object to record type information and then copy arguments to an | 223 // Use Arg() object to record type information and then copy arguments to an |
230 // array to make it easier to iterate over them. | 224 // array to make it easier to iterate over them. |
231 const internal::Arg arg_array[] = { | 225 const internal::Arg arg_array[] = { args... }; |
232 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 | 226 return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args)); |
233 }; | |
234 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
235 } | 227 } |
236 | 228 |
237 template<size_t N, | 229 template<size_t N, typename... Args> |
238 class T0, class T1, class T2, class T3, class T4, | 230 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, Args... args) { |
239 class T5, class T6, class T7, class T8, class T9> | |
240 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, | |
241 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
242 T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { | |
243 // Use Arg() object to record type information and then copy arguments to an | 231 // Use Arg() object to record type information and then copy arguments to an |
244 // array to make it easier to iterate over them. | 232 // array to make it easier to iterate over them. |
245 const internal::Arg arg_array[] = { | 233 const internal::Arg arg_array[] = { args... }; |
246 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 | 234 return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args)); |
247 }; | |
248 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
249 } | |
250 | |
251 template<class T0, class T1, class T2, class T3, class T4, | |
252 class T5, class T6, class T7, class T8> | |
253 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
254 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
255 T5 arg5, T6 arg6, T7 arg7, T8 arg8) { | |
256 // Use Arg() object to record type information and then copy arguments to an | |
257 // array to make it easier to iterate over them. | |
258 const internal::Arg arg_array[] = { | |
259 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 | |
260 }; | |
261 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
262 } | |
263 | |
264 template<size_t N, | |
265 class T0, class T1, class T2, class T3, class T4, class T5, | |
266 class T6, class T7, class T8> | |
267 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, | |
268 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
269 T5 arg5, T6 arg6, T7 arg7, T8 arg8) { | |
270 // Use Arg() object to record type information and then copy arguments to an | |
271 // array to make it easier to iterate over them. | |
272 const internal::Arg arg_array[] = { | |
273 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 | |
274 }; | |
275 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
276 } | |
277 | |
278 template<class T0, class T1, class T2, class T3, class T4, class T5, | |
279 class T6, class T7> | |
280 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
281 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
282 T5 arg5, T6 arg6, T7 arg7) { | |
283 // Use Arg() object to record type information and then copy arguments to an | |
284 // array to make it easier to iterate over them. | |
285 const internal::Arg arg_array[] = { | |
286 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 | |
287 }; | |
288 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
289 } | |
290 | |
291 template<size_t N, | |
292 class T0, class T1, class T2, class T3, class T4, class T5, | |
293 class T6, class T7> | |
294 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, | |
295 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
296 T5 arg5, T6 arg6, T7 arg7) { | |
297 // Use Arg() object to record type information and then copy arguments to an | |
298 // array to make it easier to iterate over them. | |
299 const internal::Arg arg_array[] = { | |
300 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 | |
301 }; | |
302 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
303 } | |
304 | |
305 template<class T0, class T1, class T2, class T3, class T4, class T5, | |
306 class T6> | |
307 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
308 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, | |
309 T5 arg5, T6 arg6) { | |
310 // Use Arg() object to record type information and then copy arguments to an | |
311 // array to make it easier to iterate over them. | |
312 const internal::Arg arg_array[] = { | |
313 arg0, arg1, arg2, arg3, arg4, arg5, arg6 | |
314 }; | |
315 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
316 } | |
317 | |
318 template<size_t N, | |
319 class T0, class T1, class T2, class T3, class T4, class T5, | |
320 class T6> | |
321 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, | |
322 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, | |
323 T6 arg6) { | |
324 // Use Arg() object to record type information and then copy arguments to an | |
325 // array to make it easier to iterate over them. | |
326 const internal::Arg arg_array[] = { | |
327 arg0, arg1, arg2, arg3, arg4, arg5, arg6 | |
328 }; | |
329 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
330 } | |
331 | |
332 template<class T0, class T1, class T2, class T3, class T4, class T5> | |
333 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
334 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { | |
335 // Use Arg() object to record type information and then copy arguments to an | |
336 // array to make it easier to iterate over them. | |
337 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4, arg5 }; | |
338 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
339 } | |
340 | |
341 template<size_t N, | |
342 class T0, class T1, class T2, class T3, class T4, class T5> | |
343 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, | |
344 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { | |
345 // Use Arg() object to record type information and then copy arguments to an | |
346 // array to make it easier to iterate over them. | |
347 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4, arg5 }; | |
348 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
349 } | |
350 | |
351 template<class T0, class T1, class T2, class T3, class T4> | |
352 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
353 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { | |
354 // Use Arg() object to record type information and then copy arguments to an | |
355 // array to make it easier to iterate over them. | |
356 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4 }; | |
357 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
358 } | |
359 | |
360 template<size_t N, class T0, class T1, class T2, class T3, class T4> | |
361 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1, | |
362 T2 arg2, T3 arg3, T4 arg4) { | |
363 // Use Arg() object to record type information and then copy arguments to an | |
364 // array to make it easier to iterate over them. | |
365 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4 }; | |
366 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
367 } | |
368 | |
369 template<class T0, class T1, class T2, class T3> | |
370 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
371 T0 arg0, T1 arg1, T2 arg2, T3 arg3) { | |
372 // Use Arg() object to record type information and then copy arguments to an | |
373 // array to make it easier to iterate over them. | |
374 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3 }; | |
375 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
376 } | |
377 | |
378 template<size_t N, class T0, class T1, class T2, class T3> | |
379 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, | |
380 T0 arg0, T1 arg1, T2 arg2, T3 arg3) { | |
381 // Use Arg() object to record type information and then copy arguments to an | |
382 // array to make it easier to iterate over them. | |
383 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3 }; | |
384 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
385 } | |
386 | |
387 template<class T0, class T1, class T2> | |
388 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, | |
389 T0 arg0, T1 arg1, T2 arg2) { | |
390 // Use Arg() object to record type information and then copy arguments to an | |
391 // array to make it easier to iterate over them. | |
392 const internal::Arg arg_array[] = { arg0, arg1, arg2 }; | |
393 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
394 } | |
395 | |
396 template<size_t N, class T0, class T1, class T2> | |
397 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1, | |
398 T2 arg2) { | |
399 // Use Arg() object to record type information and then copy arguments to an | |
400 // array to make it easier to iterate over them. | |
401 const internal::Arg arg_array[] = { arg0, arg1, arg2 }; | |
402 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
403 } | |
404 | |
405 template<class T0, class T1> | |
406 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, T0 arg0, T1 arg1) { | |
407 // Use Arg() object to record type information and then copy arguments to an | |
408 // array to make it easier to iterate over them. | |
409 const internal::Arg arg_array[] = { arg0, arg1 }; | |
410 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
411 } | |
412 | |
413 template<size_t N, class T0, class T1> | |
414 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1) { | |
415 // Use Arg() object to record type information and then copy arguments to an | |
416 // array to make it easier to iterate over them. | |
417 const internal::Arg arg_array[] = { arg0, arg1 }; | |
418 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
419 } | |
420 | |
421 template<class T0> | |
422 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, T0 arg0) { | |
423 // Use Arg() object to record type information and then copy arguments to an | |
424 // array to make it easier to iterate over them. | |
425 const internal::Arg arg_array[] = { arg0 }; | |
426 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
427 } | |
428 | |
429 template<size_t N, class T0> | |
430 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0) { | |
431 // Use Arg() object to record type information and then copy arguments to an | |
432 // array to make it easier to iterate over them. | |
433 const internal::Arg arg_array[] = { arg0 }; | |
434 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array)); | |
435 } | 235 } |
436 | 236 |
437 // Fast-path when we don't actually need to substitute any arguments. | 237 // Fast-path when we don't actually need to substitute any arguments. |
438 BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt); | 238 BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt); |
439 template<size_t N> | 239 template<size_t N> |
440 inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) { | 240 inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) { |
441 return SafeSNPrintf(buf, N, fmt); | 241 return SafeSNPrintf(buf, N, fmt); |
442 } | 242 } |
443 | 243 |
444 } // namespace strings | 244 } // namespace strings |
445 } // namespace base | 245 } // namespace base |
446 | 246 |
447 #endif // BASE_STRINGS_SAFE_SPRINTF_H_ | 247 #endif // BASE_STRINGS_SAFE_SPRINTF_H_ |
OLD | NEW |