/root/bitcoin/src/test/fuzz/strprintf.cpp
| Line | Count | Source | 
| 1 |  | // Copyright (c) 2020-2021 The Bitcoin Core developers | 
| 2 |  | // Distributed under the MIT software license, see the accompanying | 
| 3 |  | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | 
| 4 |  |  | 
| 5 |  | #include <test/fuzz/FuzzedDataProvider.h> | 
| 6 |  | #include <test/fuzz/fuzz.h> | 
| 7 |  | #include <test/fuzz/util.h> | 
| 8 |  | #include <tinyformat.h> | 
| 9 |  | #include <util/strencodings.h> | 
| 10 |  | #include <util/translation.h> | 
| 11 |  |  | 
| 12 |  | #include <algorithm> | 
| 13 |  | #include <cstdint> | 
| 14 |  | #include <string> | 
| 15 |  | #include <vector> | 
| 16 |  |  | 
| 17 |  | template <typename... Args> | 
| 18 |  | void fuzz_fmt(const std::string& fmt, const Args&... args) | 
| 19 | 0 | { | 
| 20 | 0 |     (void)tfm::format(tfm::RuntimeFormat{fmt}, args...); | 
| 21 | 0 | } Unexecuted instantiation: _Z8fuzz_fmtIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS5_DpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJPKcEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJaEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJhEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJcEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJbEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJfEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJsEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJtEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJlEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_Unexecuted instantiation: _Z8fuzz_fmtIJmEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEDpRKT_ | 
| 22 |  |  | 
| 23 |  | FUZZ_TARGET(str_printf) | 
| 24 | 0 | { | 
| 25 | 0 |     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); | 
| 26 | 0 |     const std::string format_string = fuzzed_data_provider.ConsumeRandomLengthString(64); | 
| 27 |  | 
 | 
| 28 | 0 |     const int digits_in_format_specifier = std::count_if(format_string.begin(), format_string.end(), IsDigit); | 
| 29 |  |  | 
| 30 |  |     // Avoid triggering the following crash bug: | 
| 31 |  |     // * strprintf("%987654321000000:", 1); | 
| 32 |  |     // | 
| 33 |  |     // Avoid triggering the following OOM bug: | 
| 34 |  |     // * strprintf("%.222222200000000$", 1.1); | 
| 35 |  |     // | 
| 36 |  |     // Upstream bug report: https://github.com/c42f/tinyformat/issues/70 | 
| 37 | 0 |     if (format_string.find('%') != std::string::npos && digits_in_format_specifier >= 7) { | 
| 38 | 0 |         return; | 
| 39 | 0 |     } | 
| 40 |  |  | 
| 41 |  |     // Avoid triggering the following crash bug: | 
| 42 |  |     // * strprintf("%1$*1$*", -11111111); | 
| 43 |  |     // | 
| 44 |  |     // Upstream bug report: https://github.com/c42f/tinyformat/issues/70 | 
| 45 | 0 |     if (format_string.find('%') != std::string::npos && format_string.find('$') != std::string::npos && format_string.find('*') != std::string::npos && digits_in_format_specifier > 0) { | 
| 46 | 0 |         return; | 
| 47 | 0 |     } | 
| 48 |  |  | 
| 49 |  |     // Avoid triggering the following crash bug: | 
| 50 |  |     // * strprintf("%.1s", (char*)nullptr); | 
| 51 |  |     // | 
| 52 |  |     // (void)strprintf(format_string, (char*)nullptr); | 
| 53 |  |     // | 
| 54 |  |     // Upstream bug report: https://github.com/c42f/tinyformat/issues/70 | 
| 55 |  |  | 
| 56 | 0 |     try { | 
| 57 | 0 |         CallOneOf( | 
| 58 | 0 |             fuzzed_data_provider, | 
| 59 | 0 |             [&] { | 
| 60 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeRandomLengthString(32)); | 
| 61 | 0 |             }, | 
| 62 | 0 |             [&] { | 
| 63 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeRandomLengthString(32).c_str()); | 
| 64 | 0 |             }, | 
| 65 | 0 |             [&] { | 
| 66 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<signed char>()); | 
| 67 | 0 |             }, | 
| 68 | 0 |             [&] { | 
| 69 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<unsigned char>()); | 
| 70 | 0 |             }, | 
| 71 | 0 |             [&] { | 
| 72 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<char>()); | 
| 73 | 0 |             }, | 
| 74 | 0 |             [&] { | 
| 75 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeBool()); | 
| 76 | 0 |             }); | 
| 77 | 0 |     } catch (const tinyformat::format_error&) { | 
| 78 | 0 |     } | 
| 79 |  | 
 | 
| 80 | 0 |     if (format_string.find('%') != std::string::npos && format_string.find('c') != std::string::npos) { | 
| 81 |  |         // Avoid triggering the following: | 
| 82 |  |         // * strprintf("%c", 1.31783e+38); | 
| 83 |  |         // tinyformat.h:244:36: runtime error: 1.31783e+38 is outside the range of representable values of type 'char' | 
| 84 | 0 |         return; | 
| 85 | 0 |     } | 
| 86 |  |  | 
| 87 | 0 |     if (format_string.find('%') != std::string::npos && format_string.find('*') != std::string::npos) { | 
| 88 |  |         // Avoid triggering the following: | 
| 89 |  |         // * strprintf("%*", -2.33527e+38); | 
| 90 |  |         // tinyformat.h:283:65: runtime error: -2.33527e+38 is outside the range of representable values of type 'int' | 
| 91 |  |         // * strprintf("%*", -2147483648); | 
| 92 |  |         // tinyformat.h:763:25: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself | 
| 93 | 0 |         return; | 
| 94 | 0 |     } | 
| 95 |  |  | 
| 96 | 0 |     try { | 
| 97 | 0 |         CallOneOf( | 
| 98 | 0 |             fuzzed_data_provider, | 
| 99 | 0 |             [&] { | 
| 100 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeFloatingPoint<float>()); | 
| 101 | 0 |             }, | 
| 102 | 0 |             [&] { | 
| 103 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeFloatingPoint<double>()); | 
| 104 | 0 |             }, | 
| 105 | 0 |             [&] { | 
| 106 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<int16_t>()); | 
| 107 | 0 |             }, | 
| 108 | 0 |             [&] { | 
| 109 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<uint16_t>()); | 
| 110 | 0 |             }, | 
| 111 | 0 |             [&] { | 
| 112 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<int32_t>()); | 
| 113 | 0 |             }, | 
| 114 | 0 |             [&] { | 
| 115 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<uint32_t>()); | 
| 116 | 0 |             }, | 
| 117 | 0 |             [&] { | 
| 118 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<int64_t>()); | 
| 119 | 0 |             }, | 
| 120 | 0 |             [&] { | 
| 121 | 0 |                 fuzz_fmt(format_string, fuzzed_data_provider.ConsumeIntegral<uint64_t>()); | 
| 122 | 0 |             }); | 
| 123 | 0 |     } catch (const tinyformat::format_error&) { | 
| 124 | 0 |     } | 
| 125 | 0 | } |