Coverage Report

Created: 2025-09-27 07:16

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