Coverage Report

Created: 2026-08-14 07:03

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