Coverage Report

Created: 2026-03-31 07:09

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.63k
    : m_ptr(ptr)
24
7.63k
    , m_N(N)
25
7.63k
  {
26
7.63k
  }
27
  // Prefix increment
28
  LimitedIterator& operator++()
29
2.55M
  {
30
2.55M
    if (m_N == 0)
31
843
      throw std::runtime_error("out of data");
32
2.54M
    ++m_ptr;
33
2.54M
    --m_N;
34
2.54M
    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.72k
{
55
7.72k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
7.72k
  if (size <= fixed_size)
57
91
    return;
58
7.63k
  T value{};
59
7.63k
  if constexpr (std::is_same_v<bool, T>) {
60
301
    value = !!data[0];
61
7.33k
  } else {
62
7.33k
    std::memcpy(&value, data, sizeof(T));
63
7.33k
  }
64
65
7.63k
  data += fixed_size;
66
7.63k
  size -= fixed_size;
67
68
7.63k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
7.63k
  const std::string_view format_string{ chardata, size };
73
74
7.63k
  try {
75
7.63k
    std::vector<char> buf(2000);
76
7.63k
    [[maybe_unused]] auto ignored =
77
7.63k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
7.63k
                      format_string,
79
7.63k
                      std::make_format_args(value));
80
7.63k
  } catch (std::exception&) {
81
2.27k
  }
82
7.63k
}
void invoke_fmt<bool>(unsigned char const*, unsigned long)
Line
Count
Source
54
307
{
55
307
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
307
  if (size <= fixed_size)
57
6
    return;
58
301
  T value{};
59
301
  if constexpr (std::is_same_v<bool, T>) {
60
301
    value = !!data[0];
61
  } else {
62
    std::memcpy(&value, data, sizeof(T));
63
  }
64
65
301
  data += fixed_size;
66
301
  size -= fixed_size;
67
68
301
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
301
  const std::string_view format_string{ chardata, size };
73
74
301
  try {
75
301
    std::vector<char> buf(2000);
76
301
    [[maybe_unused]] auto ignored =
77
301
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
301
                      format_string,
79
301
                      std::make_format_args(value));
80
301
  } catch (std::exception&) {
81
117
  }
82
301
}
void invoke_fmt<char>(unsigned char const*, unsigned long)
Line
Count
Source
54
234
{
55
234
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
234
  if (size <= fixed_size)
57
6
    return;
58
228
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
228
  } else {
62
228
    std::memcpy(&value, data, sizeof(T));
63
228
  }
64
65
228
  data += fixed_size;
66
228
  size -= fixed_size;
67
68
228
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
228
  const std::string_view format_string{ chardata, size };
73
74
228
  try {
75
228
    std::vector<char> buf(2000);
76
228
    [[maybe_unused]] auto ignored =
77
228
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
228
                      format_string,
79
228
                      std::make_format_args(value));
80
228
  } catch (std::exception&) {
81
56
  }
82
228
}
void invoke_fmt<unsigned char>(unsigned char const*, unsigned long)
Line
Count
Source
54
129
{
55
129
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
129
  if (size <= fixed_size)
57
4
    return;
58
125
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
125
  } else {
62
125
    std::memcpy(&value, data, sizeof(T));
63
125
  }
64
65
125
  data += fixed_size;
66
125
  size -= fixed_size;
67
68
125
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
125
  const std::string_view format_string{ chardata, size };
73
74
125
  try {
75
125
    std::vector<char> buf(2000);
76
125
    [[maybe_unused]] auto ignored =
77
125
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
125
                      format_string,
79
125
                      std::make_format_args(value));
80
125
  } catch (std::exception&) {
81
43
  }
82
125
}
void invoke_fmt<signed char>(unsigned char const*, unsigned long)
Line
Count
Source
54
203
{
55
203
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
203
  if (size <= fixed_size)
57
6
    return;
58
197
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
197
  } else {
62
197
    std::memcpy(&value, data, sizeof(T));
63
197
  }
64
65
197
  data += fixed_size;
66
197
  size -= fixed_size;
67
68
197
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
197
  const std::string_view format_string{ chardata, size };
73
74
197
  try {
75
197
    std::vector<char> buf(2000);
76
197
    [[maybe_unused]] auto ignored =
77
197
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
197
                      format_string,
79
197
                      std::make_format_args(value));
80
197
  } catch (std::exception&) {
81
49
  }
82
197
}
void invoke_fmt<short>(unsigned char const*, unsigned long)
Line
Count
Source
54
201
{
55
201
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
201
  if (size <= fixed_size)
57
6
    return;
58
195
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
195
  } else {
62
195
    std::memcpy(&value, data, sizeof(T));
63
195
  }
64
65
195
  data += fixed_size;
66
195
  size -= fixed_size;
67
68
195
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
195
  const std::string_view format_string{ chardata, size };
73
74
195
  try {
75
195
    std::vector<char> buf(2000);
76
195
    [[maybe_unused]] auto ignored =
77
195
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
195
                      format_string,
79
195
                      std::make_format_args(value));
80
195
  } catch (std::exception&) {
81
63
  }
82
195
}
void invoke_fmt<unsigned short>(unsigned char const*, unsigned long)
Line
Count
Source
54
135
{
55
135
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
135
  if (size <= fixed_size)
57
6
    return;
58
129
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
129
  } else {
62
129
    std::memcpy(&value, data, sizeof(T));
63
129
  }
64
65
129
  data += fixed_size;
66
129
  size -= fixed_size;
67
68
129
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
129
  const std::string_view format_string{ chardata, size };
73
74
129
  try {
75
129
    std::vector<char> buf(2000);
76
129
    [[maybe_unused]] auto ignored =
77
129
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
129
                      format_string,
79
129
                      std::make_format_args(value));
80
129
  } catch (std::exception&) {
81
37
  }
82
129
}
void invoke_fmt<int>(unsigned char const*, unsigned long)
Line
Count
Source
54
481
{
55
481
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
481
  if (size <= fixed_size)
57
6
    return;
58
475
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
475
  } else {
62
475
    std::memcpy(&value, data, sizeof(T));
63
475
  }
64
65
475
  data += fixed_size;
66
475
  size -= fixed_size;
67
68
475
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
475
  const std::string_view format_string{ chardata, size };
73
74
475
  try {
75
475
    std::vector<char> buf(2000);
76
475
    [[maybe_unused]] auto ignored =
77
475
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
475
                      format_string,
79
475
                      std::make_format_args(value));
80
475
  } catch (std::exception&) {
81
142
  }
82
475
}
void invoke_fmt<unsigned int>(unsigned char const*, unsigned long)
Line
Count
Source
54
494
{
55
494
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
494
  if (size <= fixed_size)
57
6
    return;
58
488
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
488
  } else {
62
488
    std::memcpy(&value, data, sizeof(T));
63
488
  }
64
65
488
  data += fixed_size;
66
488
  size -= fixed_size;
67
68
488
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
488
  const std::string_view format_string{ chardata, size };
73
74
488
  try {
75
488
    std::vector<char> buf(2000);
76
488
    [[maybe_unused]] auto ignored =
77
488
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
488
                      format_string,
79
488
                      std::make_format_args(value));
80
488
  } catch (std::exception&) {
81
89
  }
82
488
}
void invoke_fmt<long>(unsigned char const*, unsigned long)
Line
Count
Source
54
1.16k
{
55
1.16k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
1.16k
  if (size <= fixed_size)
57
6
    return;
58
1.16k
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
1.16k
  } else {
62
1.16k
    std::memcpy(&value, data, sizeof(T));
63
1.16k
  }
64
65
1.16k
  data += fixed_size;
66
1.16k
  size -= fixed_size;
67
68
1.16k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
1.16k
  const std::string_view format_string{ chardata, size };
73
74
1.16k
  try {
75
1.16k
    std::vector<char> buf(2000);
76
1.16k
    [[maybe_unused]] auto ignored =
77
1.16k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
1.16k
                      format_string,
79
1.16k
                      std::make_format_args(value));
80
1.16k
  } catch (std::exception&) {
81
344
  }
82
1.16k
}
void invoke_fmt<unsigned long>(unsigned char const*, unsigned long)
Line
Count
Source
54
1.32k
{
55
1.32k
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
1.32k
  if (size <= fixed_size)
57
6
    return;
58
1.32k
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
1.32k
  } else {
62
1.32k
    std::memcpy(&value, data, sizeof(T));
63
1.32k
  }
64
65
1.32k
  data += fixed_size;
66
1.32k
  size -= fixed_size;
67
68
1.32k
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
1.32k
  const std::string_view format_string{ chardata, size };
73
74
1.32k
  try {
75
1.32k
    std::vector<char> buf(2000);
76
1.32k
    [[maybe_unused]] auto ignored =
77
1.32k
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
1.32k
                      format_string,
79
1.32k
                      std::make_format_args(value));
80
1.32k
  } catch (std::exception&) {
81
463
  }
82
1.32k
}
void invoke_fmt<float>(unsigned char const*, unsigned long)
Line
Count
Source
54
715
{
55
715
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
715
  if (size <= fixed_size)
57
6
    return;
58
709
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
709
  } else {
62
709
    std::memcpy(&value, data, sizeof(T));
63
709
  }
64
65
709
  data += fixed_size;
66
709
  size -= fixed_size;
67
68
709
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
709
  const std::string_view format_string{ chardata, size };
73
74
709
  try {
75
709
    std::vector<char> buf(2000);
76
709
    [[maybe_unused]] auto ignored =
77
709
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
709
                      format_string,
79
709
                      std::make_format_args(value));
80
709
  } catch (std::exception&) {
81
221
  }
82
709
}
void invoke_fmt<double>(unsigned char const*, unsigned long)
Line
Count
Source
54
816
{
55
816
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
816
  if (size <= fixed_size)
57
6
    return;
58
810
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
810
  } else {
62
810
    std::memcpy(&value, data, sizeof(T));
63
810
  }
64
65
810
  data += fixed_size;
66
810
  size -= fixed_size;
67
68
810
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
810
  const std::string_view format_string{ chardata, size };
73
74
810
  try {
75
810
    std::vector<char> buf(2000);
76
810
    [[maybe_unused]] auto ignored =
77
810
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
810
                      format_string,
79
810
                      std::make_format_args(value));
80
810
  } catch (std::exception&) {
81
208
  }
82
810
}
void invoke_fmt<long double>(unsigned char const*, unsigned long)
Line
Count
Source
54
668
{
55
668
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
668
  if (size <= fixed_size)
57
6
    return;
58
662
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
662
  } else {
62
662
    std::memcpy(&value, data, sizeof(T));
63
662
  }
64
65
662
  data += fixed_size;
66
662
  size -= fixed_size;
67
68
662
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
662
  const std::string_view format_string{ chardata, size };
73
74
662
  try {
75
662
    std::vector<char> buf(2000);
76
662
    [[maybe_unused]] auto ignored =
77
662
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
662
                      format_string,
79
662
                      std::make_format_args(value));
80
662
  } catch (std::exception&) {
81
217
  }
82
662
}
void invoke_fmt<void*>(unsigned char const*, unsigned long)
Line
Count
Source
54
271
{
55
271
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
271
  if (size <= fixed_size)
57
3
    return;
58
268
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
268
  } else {
62
268
    std::memcpy(&value, data, sizeof(T));
63
268
  }
64
65
268
  data += fixed_size;
66
268
  size -= fixed_size;
67
68
268
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
268
  const std::string_view format_string{ chardata, size };
73
74
268
  try {
75
268
    std::vector<char> buf(2000);
76
268
    [[maybe_unused]] auto ignored =
77
268
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
268
                      format_string,
79
268
                      std::make_format_args(value));
80
268
  } catch (std::exception&) {
81
118
  }
82
268
}
void invoke_fmt<__int128>(unsigned char const*, unsigned long)
Line
Count
Source
54
278
{
55
278
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
278
  if (size <= fixed_size)
57
6
    return;
58
272
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
272
  } else {
62
272
    std::memcpy(&value, data, sizeof(T));
63
272
  }
64
65
272
  data += fixed_size;
66
272
  size -= fixed_size;
67
68
272
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
272
  const std::string_view format_string{ chardata, size };
73
74
272
  try {
75
272
    std::vector<char> buf(2000);
76
272
    [[maybe_unused]] auto ignored =
77
272
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
272
                      format_string,
79
272
                      std::make_format_args(value));
80
272
  } catch (std::exception&) {
81
40
  }
82
272
}
void invoke_fmt<unsigned __int128>(unsigned char const*, unsigned long)
Line
Count
Source
54
298
{
55
298
  static_assert(sizeof(T) <= fixed_size, "fixed_size is too small");
56
298
  if (size <= fixed_size)
57
6
    return;
58
292
  T value{};
59
  if constexpr (std::is_same_v<bool, T>) {
60
    value = !!data[0];
61
292
  } else {
62
292
    std::memcpy(&value, data, sizeof(T));
63
292
  }
64
65
292
  data += fixed_size;
66
292
  size -= fixed_size;
67
68
292
  const auto* chardata = reinterpret_cast<const char*>(data);
69
  //  std::string format_string{ chardata, chardata + size };
70
71
  //  format_string.append(10, '}');
72
292
  const std::string_view format_string{ chardata, size };
73
74
292
  try {
75
292
    std::vector<char> buf(2000);
76
292
    [[maybe_unused]] auto ignored =
77
292
      std::vformat_to(LimitedIterator(buf.data(), buf.size() - 2),
78
292
                      format_string,
79
292
                      std::make_format_args(value));
80
292
  } catch (std::exception&) {
81
68
  }
82
292
}
83
84
extern "C" int
85
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
86
7.72k
{
87
7.72k
  if (size <= 3)
88
2
    return 0;
89
90
7.72k
  try {
91
92
7.72k
    const auto first = data[0];
93
7.72k
    data++;
94
7.72k
    size--;
95
96
7.72k
    switch (first & 0xF) {
97
307
      case 0:
98
307
        invoke_fmt<bool>(data, size);
99
307
        break;
100
234
      case 1:
101
234
        invoke_fmt<char>(data, size);
102
234
        break;
103
129
      case 2:
104
129
        invoke_fmt<unsigned char>(data, size);
105
129
        break;
106
203
      case 3:
107
203
        invoke_fmt<signed char>(data, size);
108
203
        break;
109
201
      case 4:
110
201
        invoke_fmt<short>(data, size);
111
201
        break;
112
135
      case 5:
113
135
        invoke_fmt<unsigned short>(data, size);
114
135
        break;
115
481
      case 6:
116
481
        invoke_fmt<int>(data, size);
117
481
        break;
118
494
      case 7:
119
494
        invoke_fmt<unsigned int>(data, size);
120
494
        break;
121
1.16k
      case 8:
122
1.16k
        invoke_fmt<long>(data, size);
123
1.16k
        break;
124
1.32k
      case 9:
125
1.32k
        invoke_fmt<unsigned long>(data, size);
126
1.32k
        break;
127
128
715
      case 10:
129
715
        invoke_fmt<float>(data, size);
130
715
        break;
131
816
      case 11:
132
816
        invoke_fmt<double>(data, size);
133
816
        break;
134
668
      case 12:
135
668
        invoke_fmt<long double>(data, size);
136
668
        break;
137
271
      case 13:
138
271
        invoke_fmt<void*>(data, size);
139
271
        break;
140
278
      case 14:
141
278
        invoke_fmt<__int128_t>(data, size);
142
278
        break;
143
298
      case 15:
144
298
        invoke_fmt<__uint128_t>(data, size);
145
298
        break;
146
7.72k
    }
147
7.72k
  } catch (...) {
148
0
  }
149
7.72k
  return 0;
150
7.72k
}