Coverage Report

Created: 2026-02-14 08:05

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.30k
    : m_ptr(ptr)
24
7.30k
    , m_N(N)
25
7.30k
  {
26
7.30k
  }
27
  // Prefix increment
28
  LimitedIterator& operator++()
29
2.45M
  {
30
2.45M
    if (m_N == 0)
31
825
      throw std::runtime_error("out of data");
32
2.45M
    ++m_ptr;
33
2.45M
    --m_N;
34
2.45M
    return *this;
35
2.45M
  }
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.45M
  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.39k
{
55
7.39k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
7.39k
  if (size <= fixed_size)
57
88
    return;
58
7.30k
  T value{};
59
7.30k
  if constexpr (std::is_same_v<bool, T>) {
60
277
    value = !!data[0];
61
7.02k
  } else {
62
7.02k
    std::memcpy(&value, data, sizeof(T));
63
7.02k
  }
64
65
7.30k
  data += fixed_size;
66
7.30k
  size -= fixed_size;
67
68
7.30k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
7.30k
  const std::string_view format_string{ chardata, size };
73
74
7.30k
  try {
75
7.30k
    std::vector<char> buf(2000);
76
7.30k
    [[maybe_unused]] auto ignored =
77
7.30k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
7.30k
                      format_string,
79
7.30k
                      std::make_format_args(value));
80
7.30k
  } catch (std::exception&) {
81
2.23k
  }
82
7.30k
}
void invoke_fmt<bool>(unsigned char const*, unsigned long)
Line
Count
Source
54
282
{
55
282
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
282
  if (size <= fixed_size)
57
5
    return;
58
277
  T value{};
59
277
  if constexpr (std::is_same_v<bool, T>) {
60
277
    value = !!data[0];
61
  } else {
62
    std::memcpy(&value, data, sizeof(T));
63
  }
64
65
277
  data += fixed_size;
66
277
  size -= fixed_size;
67
68
277
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
277
  const std::string_view format_string{ chardata, size };
73
74
277
  try {
75
277
    std::vector<char> buf(2000);
76
277
    [[maybe_unused]] auto ignored =
77
277
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
277
                      format_string,
79
277
                      std::make_format_args(value));
80
277
  } catch (std::exception&) {
81
122
  }
82
277
}
void invoke_fmt<char>(unsigned char const*, unsigned long)
Line
Count
Source
54
251
{
55
251
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
251
  if (size <= fixed_size)
57
6
    return;
58
245
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
245
  } else {
62
245
    std::memcpy(&value, data, sizeof(T));
63
245
  }
64
65
245
  data += fixed_size;
66
245
  size -= fixed_size;
67
68
245
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
245
  const std::string_view format_string{ chardata, size };
73
74
245
  try {
75
245
    std::vector<char> buf(2000);
76
245
    [[maybe_unused]] auto ignored =
77
245
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
245
                      format_string,
79
245
                      std::make_format_args(value));
80
245
  } catch (std::exception&) {
81
64
  }
82
245
}
void invoke_fmt<unsigned char>(unsigned char const*, unsigned long)
Line
Count
Source
54
141
{
55
141
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
141
  if (size <= fixed_size)
57
4
    return;
58
137
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
137
  } else {
62
137
    std::memcpy(&value, data, sizeof(T));
63
137
  }
64
65
137
  data += fixed_size;
66
137
  size -= fixed_size;
67
68
137
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
137
  const std::string_view format_string{ chardata, size };
73
74
137
  try {
75
137
    std::vector<char> buf(2000);
76
137
    [[maybe_unused]] auto ignored =
77
137
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
137
                      format_string,
79
137
                      std::make_format_args(value));
80
137
  } catch (std::exception&) {
81
37
  }
82
137
}
void invoke_fmt<signed char>(unsigned char const*, unsigned long)
Line
Count
Source
54
187
{
55
187
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
187
  if (size <= fixed_size)
57
6
    return;
58
181
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
181
  } else {
62
181
    std::memcpy(&value, data, sizeof(T));
63
181
  }
64
65
181
  data += fixed_size;
66
181
  size -= fixed_size;
67
68
181
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
181
  const std::string_view format_string{ chardata, size };
73
74
181
  try {
75
181
    std::vector<char> buf(2000);
76
181
    [[maybe_unused]] auto ignored =
77
181
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
181
                      format_string,
79
181
                      std::make_format_args(value));
80
181
  } catch (std::exception&) {
81
47
  }
82
181
}
void invoke_fmt<short>(unsigned char const*, unsigned long)
Line
Count
Source
54
171
{
55
171
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
171
  if (size <= fixed_size)
57
6
    return;
58
165
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
165
  } else {
62
165
    std::memcpy(&value, data, sizeof(T));
63
165
  }
64
65
165
  data += fixed_size;
66
165
  size -= fixed_size;
67
68
165
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
165
  const std::string_view format_string{ chardata, size };
73
74
165
  try {
75
165
    std::vector<char> buf(2000);
76
165
    [[maybe_unused]] auto ignored =
77
165
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
165
                      format_string,
79
165
                      std::make_format_args(value));
80
165
  } catch (std::exception&) {
81
52
  }
82
165
}
void invoke_fmt<unsigned short>(unsigned char const*, unsigned long)
Line
Count
Source
54
135
{
55
135
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
135
  if (size <= fixed_size)
57
6
    return;
58
129
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
129
  } else {
62
129
    std::memcpy(&value, data, sizeof(T));
63
129
  }
64
65
129
  data += fixed_size;
66
129
  size -= fixed_size;
67
68
129
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
129
  const std::string_view format_string{ chardata, size };
73
74
129
  try {
75
129
    std::vector<char> buf(2000);
76
129
    [[maybe_unused]] auto ignored =
77
129
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
129
                      format_string,
79
129
                      std::make_format_args(value));
80
129
  } catch (std::exception&) {
81
35
  }
82
129
}
void invoke_fmt<int>(unsigned char const*, unsigned long)
Line
Count
Source
54
460
{
55
460
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
460
  if (size <= fixed_size)
57
6
    return;
58
454
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
454
  } else {
62
454
    std::memcpy(&value, data, sizeof(T));
63
454
  }
64
65
454
  data += fixed_size;
66
454
  size -= fixed_size;
67
68
454
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
454
  const std::string_view format_string{ chardata, size };
73
74
454
  try {
75
454
    std::vector<char> buf(2000);
76
454
    [[maybe_unused]] auto ignored =
77
454
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
454
                      format_string,
79
454
                      std::make_format_args(value));
80
454
  } catch (std::exception&) {
81
131
  }
82
454
}
void invoke_fmt<unsigned int>(unsigned char const*, unsigned long)
Line
Count
Source
54
441
{
55
441
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
441
  if (size <= fixed_size)
57
5
    return;
58
436
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
436
  } else {
62
436
    std::memcpy(&value, data, sizeof(T));
63
436
  }
64
65
436
  data += fixed_size;
66
436
  size -= fixed_size;
67
68
436
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
436
  const std::string_view format_string{ chardata, size };
73
74
436
  try {
75
436
    std::vector<char> buf(2000);
76
436
    [[maybe_unused]] auto ignored =
77
436
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
436
                      format_string,
79
436
                      std::make_format_args(value));
80
436
  } catch (std::exception&) {
81
80
  }
82
436
}
void invoke_fmt<long>(unsigned char const*, unsigned long)
Line
Count
Source
54
1.13k
{
55
1.13k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
1.13k
  if (size <= fixed_size)
57
6
    return;
58
1.12k
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
1.12k
  } else {
62
1.12k
    std::memcpy(&value, data, sizeof(T));
63
1.12k
  }
64
65
1.12k
  data += fixed_size;
66
1.12k
  size -= fixed_size;
67
68
1.12k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
1.12k
  const std::string_view format_string{ chardata, size };
73
74
1.12k
  try {
75
1.12k
    std::vector<char> buf(2000);
76
1.12k
    [[maybe_unused]] auto ignored =
77
1.12k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
1.12k
                      format_string,
79
1.12k
                      std::make_format_args(value));
80
1.12k
  } catch (std::exception&) {
81
334
  }
82
1.12k
}
void invoke_fmt<unsigned long>(unsigned char const*, unsigned long)
Line
Count
Source
54
1.28k
{
55
1.28k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
1.28k
  if (size <= fixed_size)
57
6
    return;
58
1.27k
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
1.27k
  } else {
62
1.27k
    std::memcpy(&value, data, sizeof(T));
63
1.27k
  }
64
65
1.27k
  data += fixed_size;
66
1.27k
  size -= fixed_size;
67
68
1.27k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
1.27k
  const std::string_view format_string{ chardata, size };
73
74
1.27k
  try {
75
1.27k
    std::vector<char> buf(2000);
76
1.27k
    [[maybe_unused]] auto ignored =
77
1.27k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
1.27k
                      format_string,
79
1.27k
                      std::make_format_args(value));
80
1.27k
  } catch (std::exception&) {
81
472
  }
82
1.27k
}
void invoke_fmt<float>(unsigned char const*, unsigned long)
Line
Count
Source
54
679
{
55
679
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
679
  if (size <= fixed_size)
57
5
    return;
58
674
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
674
  } else {
62
674
    std::memcpy(&value, data, sizeof(T));
63
674
  }
64
65
674
  data += fixed_size;
66
674
  size -= fixed_size;
67
68
674
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
674
  const std::string_view format_string{ chardata, size };
73
74
674
  try {
75
674
    std::vector<char> buf(2000);
76
674
    [[maybe_unused]] auto ignored =
77
674
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
674
                      format_string,
79
674
                      std::make_format_args(value));
80
674
  } catch (std::exception&) {
81
198
  }
82
674
}
void invoke_fmt<double>(unsigned char const*, unsigned long)
Line
Count
Source
54
783
{
55
783
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
783
  if (size <= fixed_size)
57
6
    return;
58
777
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
777
  } else {
62
777
    std::memcpy(&value, data, sizeof(T));
63
777
  }
64
65
777
  data += fixed_size;
66
777
  size -= fixed_size;
67
68
777
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
777
  const std::string_view format_string{ chardata, size };
73
74
777
  try {
75
777
    std::vector<char> buf(2000);
76
777
    [[maybe_unused]] auto ignored =
77
777
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
777
                      format_string,
79
777
                      std::make_format_args(value));
80
777
  } catch (std::exception&) {
81
221
  }
82
777
}
void invoke_fmt<long double>(unsigned char const*, unsigned long)
Line
Count
Source
54
639
{
55
639
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
639
  if (size <= fixed_size)
57
6
    return;
58
633
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
633
  } else {
62
633
    std::memcpy(&value, data, sizeof(T));
63
633
  }
64
65
633
  data += fixed_size;
66
633
  size -= fixed_size;
67
68
633
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
633
  const std::string_view format_string{ chardata, size };
73
74
633
  try {
75
633
    std::vector<char> buf(2000);
76
633
    [[maybe_unused]] auto ignored =
77
633
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
633
                      format_string,
79
633
                      std::make_format_args(value));
80
633
  } catch (std::exception&) {
81
235
  }
82
633
}
void invoke_fmt<void*>(unsigned char const*, unsigned long)
Line
Count
Source
54
243
{
55
243
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
243
  if (size <= fixed_size)
57
3
    return;
58
240
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
240
  } else {
62
240
    std::memcpy(&value, data, sizeof(T));
63
240
  }
64
65
240
  data += fixed_size;
66
240
  size -= fixed_size;
67
68
240
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
240
  const std::string_view format_string{ chardata, size };
73
74
240
  try {
75
240
    std::vector<char> buf(2000);
76
240
    [[maybe_unused]] auto ignored =
77
240
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
240
                      format_string,
79
240
                      std::make_format_args(value));
80
240
  } catch (std::exception&) {
81
98
  }
82
240
}
void invoke_fmt<__int128>(unsigned char const*, unsigned long)
Line
Count
Source
54
267
{
55
267
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
267
  if (size <= fixed_size)
57
6
    return;
58
261
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
261
  } else {
62
261
    std::memcpy(&value, data, sizeof(T));
63
261
  }
64
65
261
  data += fixed_size;
66
261
  size -= fixed_size;
67
68
261
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
261
  const std::string_view format_string{ chardata, size };
73
74
261
  try {
75
261
    std::vector<char> buf(2000);
76
261
    [[maybe_unused]] auto ignored =
77
261
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
261
                      format_string,
79
261
                      std::make_format_args(value));
80
261
  } catch (std::exception&) {
81
38
  }
82
261
}
void invoke_fmt<unsigned __int128>(unsigned char const*, unsigned long)
Line
Count
Source
54
296
{
55
296
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
296
  if (size <= fixed_size)
57
6
    return;
58
290
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
290
  } else {
62
290
    std::memcpy(&value, data, sizeof(T));
63
290
  }
64
65
290
  data += fixed_size;
66
290
  size -= fixed_size;
67
68
290
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
290
  const std::string_view format_string{ chardata, size };
73
74
290
  try {
75
290
    std::vector<char> buf(2000);
76
290
    [[maybe_unused]] auto ignored =
77
290
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
290
                      format_string,
79
290
                      std::make_format_args(value));
80
290
  } catch (std::exception&) {
81
74
  }
82
290
}
83
84
extern "C" int
85
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
86
7.39k
{
87
7.39k
  if (size <= 3)
88
2
    return 0;
89
90
7.39k
  try {
91
92
7.39k
    const auto first = data[0];
93
7.39k
    data++;
94
7.39k
    size--;
95
96
7.39k
    switch (first & 0xF) {
97
282
      case 0:
98
282
        invoke_fmt<bool>(data, size);
99
282
        break;
100
251
      case 1:
101
251
        invoke_fmt<char>(data, size);
102
251
        break;
103
141
      case 2:
104
141
        invoke_fmt<unsigned char>(data, size);
105
141
        break;
106
187
      case 3:
107
187
        invoke_fmt<signed char>(data, size);
108
187
        break;
109
171
      case 4:
110
171
        invoke_fmt<short>(data, size);
111
171
        break;
112
135
      case 5:
113
135
        invoke_fmt<unsigned short>(data, size);
114
135
        break;
115
460
      case 6:
116
460
        invoke_fmt<int>(data, size);
117
460
        break;
118
441
      case 7:
119
441
        invoke_fmt<unsigned int>(data, size);
120
441
        break;
121
1.13k
      case 8:
122
1.13k
        invoke_fmt<long>(data, size);
123
1.13k
        break;
124
1.28k
      case 9:
125
1.28k
        invoke_fmt<unsigned long>(data, size);
126
1.28k
        break;
127
128
679
      case 10:
129
679
        invoke_fmt<float>(data, size);
130
679
        break;
131
783
      case 11:
132
783
        invoke_fmt<double>(data, size);
133
783
        break;
134
639
      case 12:
135
639
        invoke_fmt<long double>(data, size);
136
639
        break;
137
243
      case 13:
138
243
        invoke_fmt<void*>(data, size);
139
243
        break;
140
267
      case 14:
141
267
        invoke_fmt<__int128_t>(data, size);
142
267
        break;
143
296
      case 15:
144
296
        invoke_fmt<__uint128_t>(data, size);
145
296
        break;
146
7.39k
    }
147
7.39k
  } catch (...) {
148
0
  }
149
7.39k
  return 0;
150
7.39k
}