1 // Copyright 2013 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "partition_alloc/partition_alloc_base/strings/stringprintf.h" 6 7 #include <cstdarg> 8 #include <cstdio> 9 10 #include "partition_alloc/partition_alloc_base/compiler_specific.h" 11 #include "partition_alloc/partition_alloc_base/scoped_clear_last_error.h" 12 13 namespace partition_alloc::internal::base { 14 15 std::string PA_PRINTF_FORMAT(1, 2) TruncatingStringPrintf(const char * format,...)16 TruncatingStringPrintf(const char* format, ...) { 17 base::ScopedClearLastError last_error; 18 char stack_buf[kMaxLengthOfTruncatingStringPrintfResult + 1]; 19 va_list arguments; 20 va_start(arguments, format); 21 #if BUILDFLAG(IS_WIN) 22 int result = vsnprintf_s(stack_buf, std::size(stack_buf), _TRUNCATE, format, 23 arguments); 24 #else 25 int result = vsnprintf(stack_buf, std::size(stack_buf), format, arguments); 26 #endif 27 va_end(arguments); 28 #if BUILDFLAG(IS_WIN) 29 // If an output error is encountered or data is larger than count, 30 // a negative value is returned. So to see whether an output error is really 31 // encountered or not, need to see errno. If errno == EINVAL or 32 // errno == ERANGE, an output error is encountered. If not, an output is 33 // just truncated. 34 if (result < 0 && (errno == EINVAL || errno == ERANGE)) { 35 return std::string(); 36 } 37 #else 38 // If an output error is encountered, a negative value is returned. 39 // In the case, return an empty string. 40 if (result < 0) { 41 return std::string(); 42 } 43 #endif 44 // If result is equal or larger than std::size(stack_buf), the output was 45 // truncated. ::base::StringPrintf doesn't truncate output. 46 return std::string(stack_buf); 47 } 48 49 } // namespace partition_alloc::internal::base 50