Coverage Report

Created: 2025-11-16 07:18

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