Coverage Report

Created: 2025-12-31 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/one-arg.cpp
Line
Count
Source
1
// Copyright (c) 2023, Paul Dreik
2
// Licensed under Boost software license 1.0
3
// SPDX-License-Identifier: BSL-1.0
4
5
#include <cstdint>
6
#include <cstring>
7
#include <exception>
8
#include <format>
9
#include <string_view>
10
#include <vector>
11
12
constexpr std::size_t fixed_size = 16;
13
14
struct LimitedIterator
15
{
16
  using iterator_category = std::random_access_iterator_tag;
17
  using difference_type = std::ptrdiff_t;
18
  using value_type = char;
19
  using pointer = char*;
20
  using reference = char&;
21
22
  explicit LimitedIterator(char* ptr, std::size_t N)
23
7.57k
    : m_ptr(ptr)
24
7.57k
    , m_N(N)
25
7.57k
  {
26
7.57k
  }
27
  // Prefix increment
28
  LimitedIterator& operator++()
29
2.51M
  {
30
2.51M
    if (m_N == 0)
31
843
      throw std::runtime_error("out of data");
32
2.51M
    ++m_ptr;
33
2.51M
    --m_N;
34
2.51M
    return *this;
35
2.51M
  }
36
  // Postfix increment
37
  LimitedIterator operator++(int)
38
0
  {
39
0
    if (m_N == 0)
40
0
      throw std::runtime_error("out of data");
41
0
    LimitedIterator tmp = *this;
42
0
    ++m_ptr;
43
0
    --m_N;
44
0
    return tmp;
45
0
  }
46
2.51M
  char& operator*() { return *m_ptr; }
47
  char* m_ptr{};
48
  std::size_t m_N;
49
};
50
51
template<typename T>
52
void
53
invoke_fmt(const uint8_t* data, size_t size)
54
7.66k
{
55
7.66k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
7.66k
  if (size <= fixed_size)
57
90
    return;
58
7.57k
  T value{};
59
7.57k
  if constexpr (std::is_same_v<bool, T>) {
60
283
    value = !!data[0];
61
7.29k
  } else {
62
7.29k
    std::memcpy(&value, data, sizeof(T));
63
7.29k
  }
64
65
7.57k
  data += fixed_size;
66
7.57k
  size -= fixed_size;
67
68
7.57k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
7.57k
  const std::string_view format_string{ chardata, size };
73
74
7.57k
  try {
75
7.57k
    std::vector<char> buf(2000);
76
7.57k
    [[maybe_unused]] auto ignored =
77
7.57k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
7.57k
                      format_string,
79
7.57k
                      std::make_format_args(value));
80
7.57k
  } catch (std::exception&) {
81
2.32k
  }
82
7.57k
}
void invoke_fmt<bool>(unsigned char const*, unsigned long)
Line
Count
Source
54
289
{
55
289
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
289
  if (size <= fixed_size)
57
6
    return;
58
283
  T value{};
59
283
  if constexpr (std::is_same_v<bool, T>) {
60
283
    value = !!data[0];
61
  } else {
62
    std::memcpy(&value, data, sizeof(T));
63
  }
64
65
283
  data += fixed_size;
66
283
  size -= fixed_size;
67
68
283
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
283
  const std::string_view format_string{ chardata, size };
73
74
283
  try {
75
283
    std::vector<char> buf(2000);
76
283
    [[maybe_unused]] auto ignored =
77
283
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
283
                      format_string,
79
283
                      std::make_format_args(value));
80
283
  } catch (std::exception&) {
81
113
  }
82
283
}
void invoke_fmt<char>(unsigned char const*, unsigned long)
Line
Count
Source
54
258
{
55
258
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
258
  if (size <= fixed_size)
57
6
    return;
58
252
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
252
  } else {
62
252
    std::memcpy(&value, data, sizeof(T));
63
252
  }
64
65
252
  data += fixed_size;
66
252
  size -= fixed_size;
67
68
252
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
252
  const std::string_view format_string{ chardata, size };
73
74
252
  try {
75
252
    std::vector<char> buf(2000);
76
252
    [[maybe_unused]] auto ignored =
77
252
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
252
                      format_string,
79
252
                      std::make_format_args(value));
80
252
  } catch (std::exception&) {
81
76
  }
82
252
}
void invoke_fmt<unsigned char>(unsigned char const*, unsigned long)
Line
Count
Source
54
152
{
55
152
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
152
  if (size <= fixed_size)
57
3
    return;
58
149
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
149
  } else {
62
149
    std::memcpy(&value, data, sizeof(T));
63
149
  }
64
65
149
  data += fixed_size;
66
149
  size -= fixed_size;
67
68
149
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
149
  const std::string_view format_string{ chardata, size };
73
74
149
  try {
75
149
    std::vector<char> buf(2000);
76
149
    [[maybe_unused]] auto ignored =
77
149
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
149
                      format_string,
79
149
                      std::make_format_args(value));
80
149
  } catch (std::exception&) {
81
41
  }
82
149
}
void invoke_fmt<signed char>(unsigned char const*, unsigned long)
Line
Count
Source
54
183
{
55
183
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
183
  if (size <= fixed_size)
57
6
    return;
58
177
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
177
  } else {
62
177
    std::memcpy(&value, data, sizeof(T));
63
177
  }
64
65
177
  data += fixed_size;
66
177
  size -= fixed_size;
67
68
177
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
177
  const std::string_view format_string{ chardata, size };
73
74
177
  try {
75
177
    std::vector<char> buf(2000);
76
177
    [[maybe_unused]] auto ignored =
77
177
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
177
                      format_string,
79
177
                      std::make_format_args(value));
80
177
  } catch (std::exception&) {
81
45
  }
82
177
}
void invoke_fmt<short>(unsigned char const*, unsigned long)
Line
Count
Source
54
180
{
55
180
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
180
  if (size <= fixed_size)
57
6
    return;
58
174
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
174
  } else {
62
174
    std::memcpy(&value, data, sizeof(T));
63
174
  }
64
65
174
  data += fixed_size;
66
174
  size -= fixed_size;
67
68
174
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
174
  const std::string_view format_string{ chardata, size };
73
74
174
  try {
75
174
    std::vector<char> buf(2000);
76
174
    [[maybe_unused]] auto ignored =
77
174
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
174
                      format_string,
79
174
                      std::make_format_args(value));
80
174
  } catch (std::exception&) {
81
49
  }
82
174
}
void invoke_fmt<unsigned short>(unsigned char const*, unsigned long)
Line
Count
Source
54
112
{
55
112
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
112
  if (size <= fixed_size)
57
6
    return;
58
106
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
106
  } else {
62
106
    std::memcpy(&value, data, sizeof(T));
63
106
  }
64
65
106
  data += fixed_size;
66
106
  size -= fixed_size;
67
68
106
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
106
  const std::string_view format_string{ chardata, size };
73
74
106
  try {
75
106
    std::vector<char> buf(2000);
76
106
    [[maybe_unused]] auto ignored =
77
106
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
106
                      format_string,
79
106
                      std::make_format_args(value));
80
106
  } catch (std::exception&) {
81
33
  }
82
106
}
void invoke_fmt<int>(unsigned char const*, unsigned long)
Line
Count
Source
54
489
{
55
489
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
489
  if (size <= fixed_size)
57
6
    return;
58
483
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
483
  } else {
62
483
    std::memcpy(&value, data, sizeof(T));
63
483
  }
64
65
483
  data += fixed_size;
66
483
  size -= fixed_size;
67
68
483
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
483
  const std::string_view format_string{ chardata, size };
73
74
483
  try {
75
483
    std::vector<char> buf(2000);
76
483
    [[maybe_unused]] auto ignored =
77
483
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
483
                      format_string,
79
483
                      std::make_format_args(value));
80
483
  } catch (std::exception&) {
81
146
  }
82
483
}
void invoke_fmt<unsigned int>(unsigned char const*, unsigned long)
Line
Count
Source
54
482
{
55
482
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
482
  if (size <= fixed_size)
57
6
    return;
58
476
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
476
  } else {
62
476
    std::memcpy(&value, data, sizeof(T));
63
476
  }
64
65
476
  data += fixed_size;
66
476
  size -= fixed_size;
67
68
476
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
476
  const std::string_view format_string{ chardata, size };
73
74
476
  try {
75
476
    std::vector<char> buf(2000);
76
476
    [[maybe_unused]] auto ignored =
77
476
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
476
                      format_string,
79
476
                      std::make_format_args(value));
80
476
  } catch (std::exception&) {
81
74
  }
82
476
}
void invoke_fmt<long>(unsigned char const*, unsigned long)
Line
Count
Source
54
1.20k
{
55
1.20k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
1.20k
  if (size <= fixed_size)
57
5
    return;
58
1.20k
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
1.20k
  } else {
62
1.20k
    std::memcpy(&value, data, sizeof(T));
63
1.20k
  }
64
65
1.20k
  data += fixed_size;
66
1.20k
  size -= fixed_size;
67
68
1.20k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
1.20k
  const std::string_view format_string{ chardata, size };
73
74
1.20k
  try {
75
1.20k
    std::vector<char> buf(2000);
76
1.20k
    [[maybe_unused]] auto ignored =
77
1.20k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
1.20k
                      format_string,
79
1.20k
                      std::make_format_args(value));
80
1.20k
  } catch (std::exception&) {
81
370
  }
82
1.20k
}
void invoke_fmt<unsigned long>(unsigned char const*, unsigned long)
Line
Count
Source
54
1.34k
{
55
1.34k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
1.34k
  if (size <= fixed_size)
57
6
    return;
58
1.33k
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
1.33k
  } else {
62
1.33k
    std::memcpy(&value, data, sizeof(T));
63
1.33k
  }
64
65
1.33k
  data += fixed_size;
66
1.33k
  size -= fixed_size;
67
68
1.33k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
1.33k
  const std::string_view format_string{ chardata, size };
73
74
1.33k
  try {
75
1.33k
    std::vector<char> buf(2000);
76
1.33k
    [[maybe_unused]] auto ignored =
77
1.33k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
1.33k
                      format_string,
79
1.33k
                      std::make_format_args(value));
80
1.33k
  } catch (std::exception&) {
81
490
  }
82
1.33k
}
void invoke_fmt<float>(unsigned char const*, unsigned long)
Line
Count
Source
54
690
{
55
690
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
690
  if (size <= fixed_size)
57
6
    return;
58
684
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
684
  } else {
62
684
    std::memcpy(&value, data, sizeof(T));
63
684
  }
64
65
684
  data += fixed_size;
66
684
  size -= fixed_size;
67
68
684
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
684
  const std::string_view format_string{ chardata, size };
73
74
684
  try {
75
684
    std::vector<char> buf(2000);
76
684
    [[maybe_unused]] auto ignored =
77
684
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
684
                      format_string,
79
684
                      std::make_format_args(value));
80
684
  } catch (std::exception&) {
81
206
  }
82
684
}
void invoke_fmt<double>(unsigned char const*, unsigned long)
Line
Count
Source
54
807
{
55
807
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
807
  if (size <= fixed_size)
57
6
    return;
58
801
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
801
  } else {
62
801
    std::memcpy(&value, data, sizeof(T));
63
801
  }
64
65
801
  data += fixed_size;
66
801
  size -= fixed_size;
67
68
801
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
801
  const std::string_view format_string{ chardata, size };
73
74
801
  try {
75
801
    std::vector<char> buf(2000);
76
801
    [[maybe_unused]] auto ignored =
77
801
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
801
                      format_string,
79
801
                      std::make_format_args(value));
80
801
  } catch (std::exception&) {
81
218
  }
82
801
}
void invoke_fmt<long double>(unsigned char const*, unsigned long)
Line
Count
Source
54
652
{
55
652
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
652
  if (size <= fixed_size)
57
6
    return;
58
646
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
646
  } else {
62
646
    std::memcpy(&value, data, sizeof(T));
63
646
  }
64
65
646
  data += fixed_size;
66
646
  size -= fixed_size;
67
68
646
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
646
  const std::string_view format_string{ chardata, size };
73
74
646
  try {
75
646
    std::vector<char> buf(2000);
76
646
    [[maybe_unused]] auto ignored =
77
646
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
646
                      format_string,
79
646
                      std::make_format_args(value));
80
646
  } catch (std::exception&) {
81
232
  }
82
646
}
void invoke_fmt<void*>(unsigned char const*, unsigned long)
Line
Count
Source
54
264
{
55
264
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
264
  if (size <= fixed_size)
57
4
    return;
58
260
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
260
  } else {
62
260
    std::memcpy(&value, data, sizeof(T));
63
260
  }
64
65
260
  data += fixed_size;
66
260
  size -= fixed_size;
67
68
260
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
260
  const std::string_view format_string{ chardata, size };
73
74
260
  try {
75
260
    std::vector<char> buf(2000);
76
260
    [[maybe_unused]] auto ignored =
77
260
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
260
                      format_string,
79
260
                      std::make_format_args(value));
80
260
  } catch (std::exception&) {
81
127
  }
82
260
}
void invoke_fmt<__int128>(unsigned char const*, unsigned long)
Line
Count
Source
54
278
{
55
278
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
278
  if (size <= fixed_size)
57
6
    return;
58
272
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
272
  } else {
62
272
    std::memcpy(&value, data, sizeof(T));
63
272
  }
64
65
272
  data += fixed_size;
66
272
  size -= fixed_size;
67
68
272
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
272
  const std::string_view format_string{ chardata, size };
73
74
272
  try {
75
272
    std::vector<char> buf(2000);
76
272
    [[maybe_unused]] auto ignored =
77
272
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
272
                      format_string,
79
272
                      std::make_format_args(value));
80
272
  } catch (std::exception&) {
81
47
  }
82
272
}
void invoke_fmt<unsigned __int128>(unsigned char const*, unsigned long)
Line
Count
Source
54
281
{
55
281
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
281
  if (size <= fixed_size)
57
6
    return;
58
275
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
275
  } else {
62
275
    std::memcpy(&value, data, sizeof(T));
63
275
  }
64
65
275
  data += fixed_size;
66
275
  size -= fixed_size;
67
68
275
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
275
  const std::string_view format_string{ chardata, size };
73
74
275
  try {
75
275
    std::vector<char> buf(2000);
76
275
    [[maybe_unused]] auto ignored =
77
275
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
275
                      format_string,
79
275
                      std::make_format_args(value));
80
275
  } catch (std::exception&) {
81
62
  }
82
275
}
83
84
extern "C" int
85
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
86
7.67k
{
87
7.67k
  if (size <= 3)
88
2
    return 0;
89
90
7.66k
  try {
91
92
7.66k
    const auto first = data[0];
93
7.66k
    data++;
94
7.66k
    size--;
95
96
7.66k
    switch (first & 0xF) {
97
289
      case 0:
98
289
        invoke_fmt<bool>(data, size);
99
289
        break;
100
258
      case 1:
101
258
        invoke_fmt<char>(data, size);
102
258
        break;
103
152
      case 2:
104
152
        invoke_fmt<unsigned char>(data, size);
105
152
        break;
106
183
      case 3:
107
183
        invoke_fmt<signed char>(data, size);
108
183
        break;
109
180
      case 4:
110
180
        invoke_fmt<short>(data, size);
111
180
        break;
112
112
      case 5:
113
112
        invoke_fmt<unsigned short>(data, size);
114
112
        break;
115
489
      case 6:
116
489
        invoke_fmt<int>(data, size);
117
489
        break;
118
482
      case 7:
119
482
        invoke_fmt<unsigned int>(data, size);
120
482
        break;
121
1.20k
      case 8:
122
1.20k
        invoke_fmt<long>(data, size);
123
1.20k
        break;
124
1.34k
      case 9:
125
1.34k
        invoke_fmt<unsigned long>(data, size);
126
1.34k
        break;
127
128
690
      case 10:
129
690
        invoke_fmt<float>(data, size);
130
690
        break;
131
807
      case 11:
132
807
        invoke_fmt<double>(data, size);
133
807
        break;
134
652
      case 12:
135
652
        invoke_fmt<long double>(data, size);
136
652
        break;
137
264
      case 13:
138
264
        invoke_fmt<void*>(data, size);
139
264
        break;
140
278
      case 14:
141
278
        invoke_fmt<__int128_t>(data, size);
142
278
        break;
143
281
      case 15:
144
281
        invoke_fmt<__uint128_t>(data, size);
145
281
        break;
146
7.66k
    }
147
7.66k
  } catch (...) {
148
0
  }
149
7.66k
  return 0;
150
7.66k
}