|
23 | 23 | #include <algorithm> |
24 | 24 | #include <set> |
25 | 25 | #include <limits> |
| 26 | +#include <utility> |
| 27 | +#include <boost/container/small_vector.hpp> |
26 | 28 |
|
27 | 29 | // ----------------------- |
28 | 30 | namespace ceph { |
@@ -365,10 +367,21 @@ std::ostream& JSONFormatter::dump_stream(std::string_view name) |
365 | 367 |
|
366 | 368 | void JSONFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) |
367 | 369 | { |
368 | | - char buf[LARGE_SIZE]; |
369 | | - vsnprintf(buf, LARGE_SIZE, fmt, ap); |
| 370 | + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ |
| 371 | + LARGE_SIZE, boost::container::default_init}; |
370 | 372 |
|
371 | | - add_value(name, buf, quoted); |
| 373 | + va_list ap_copy; |
| 374 | + va_copy(ap_copy, ap); |
| 375 | + int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy); |
| 376 | + va_end(ap_copy); |
| 377 | + |
| 378 | + if (std::cmp_greater_equal(len, buf.size())) { |
| 379 | + // output was truncated, allocate a buffer large enough |
| 380 | + buf.resize(len + 1, boost::container::default_init); |
| 381 | + vsnprintf(buf.data(), buf.size(), fmt, ap); |
| 382 | + } |
| 383 | + |
| 384 | + add_value(name, buf.data(), quoted); |
372 | 385 | } |
373 | 386 |
|
374 | 387 | int JSONFormatter::get_len() const |
@@ -550,15 +563,27 @@ std::ostream& XMLFormatter::dump_stream(std::string_view name) |
550 | 563 |
|
551 | 564 | void XMLFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) |
552 | 565 | { |
553 | | - char buf[LARGE_SIZE]; |
554 | | - size_t len = vsnprintf(buf, LARGE_SIZE, fmt, ap); |
| 566 | + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ |
| 567 | + LARGE_SIZE, boost::container::default_init}; |
| 568 | + |
| 569 | + va_list ap_copy; |
| 570 | + va_copy(ap_copy, ap); |
| 571 | + int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy); |
| 572 | + va_end(ap_copy); |
| 573 | + |
| 574 | + if (std::cmp_greater_equal(len, buf.size())) { |
| 575 | + // output was truncated, allocate a buffer large enough |
| 576 | + buf.resize(len + 1, boost::container::default_init); |
| 577 | + vsnprintf(buf.data(), buf.size(), fmt, ap); |
| 578 | + } |
| 579 | + |
555 | 580 | auto e = get_xml_name(name); |
556 | 581 |
|
557 | 582 | print_spaces(); |
558 | 583 | if (ns) { |
559 | | - m_ss << "<" << e << " xmlns=\"" << ns << "\">" << xml_stream_escaper(std::string_view(buf, len)) << "</" << e << ">"; |
| 584 | + m_ss << "<" << e << " xmlns=\"" << ns << "\">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">"; |
560 | 585 | } else { |
561 | | - m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf, len)) << "</" << e << ">"; |
| 586 | + m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">"; |
562 | 587 | } |
563 | 588 |
|
564 | 589 | if (m_pretty) |
@@ -927,14 +952,26 @@ void TableFormatter::dump_format_va(std::string_view name, |
927 | 952 | const char *fmt, va_list ap) |
928 | 953 | { |
929 | 954 | finish_pending_string(); |
930 | | - char buf[LARGE_SIZE]; |
931 | | - vsnprintf(buf, LARGE_SIZE, fmt, ap); |
| 955 | + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ |
| 956 | + LARGE_SIZE, boost::container::default_init}; |
| 957 | + |
| 958 | + va_list ap_copy; |
| 959 | + va_copy(ap_copy, ap); |
| 960 | + int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy); |
| 961 | + va_end(ap_copy); |
| 962 | + |
| 963 | + if (std::cmp_greater_equal(len, buf.size())) { |
| 964 | + // output was truncated, allocate a buffer large enough |
| 965 | + buf.resize(len + 1, boost::container::default_init); |
| 966 | + vsnprintf(buf.data(), buf.size(), fmt, ap); |
| 967 | + } |
932 | 968 |
|
933 | 969 | size_t i = m_vec_index(name); |
934 | 970 | if (ns) { |
935 | | - m_ss << ns << "." << buf; |
936 | | - } else |
937 | | - m_ss << buf; |
| 971 | + m_ss << ns << "." << buf.data(); |
| 972 | + } else { |
| 973 | + m_ss << buf.data(); |
| 974 | + } |
938 | 975 |
|
939 | 976 | m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str())); |
940 | 977 | m_ss.clear(); |
|
0 commit comments