| 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 |