Coverage Report

Created: 2026-06-30 08:02

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