Coverage Report

Created: 2025-11-15 07:27

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