Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
82c4e223
Commit
82c4e223
authored
Oct 13, 2020
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup fuzzing
parent
63e40c96
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
126 additions
and
153 deletions
+126
-153
test/fuzzing/chrono-duration.cc
test/fuzzing/chrono-duration.cc
+41
-45
test/fuzzing/fuzzer-common.h
test/fuzzing/fuzzer-common.h
+27
-6
test/fuzzing/main.cc
test/fuzzing/main.cc
+1
-1
test/fuzzing/named-arg.cc
test/fuzzing/named-arg.cc
+23
-37
test/fuzzing/one-arg.cc
test/fuzzing/one-arg.cc
+20
-48
test/fuzzing/two-args.cc
test/fuzzing/two-args.cc
+14
-16
No files found.
test/fuzzing/chrono-duration.cc
View file @
82c4e223
...
@@ -6,9 +6,9 @@
...
@@ -6,9 +6,9 @@
#include "fuzzer-common.h"
#include "fuzzer-common.h"
template
<
typename
Item
,
typename
Ratio
>
template
<
typename
Period
,
typename
Rep
>
void
invoke_inner
(
fmt
::
string_view
format_str
,
Item
item
)
{
void
invoke_inner
(
fmt
::
string_view
format_str
,
Rep
rep
)
{
auto
value
=
std
::
chrono
::
duration
<
Item
,
Ratio
>
(
item
);
auto
value
=
std
::
chrono
::
duration
<
Rep
,
Period
>
(
rep
);
try
{
try
{
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
format_str
,
value
);
std
::
string
message
=
fmt
::
format
(
format_str
,
value
);
...
@@ -20,71 +20,67 @@ void invoke_inner(fmt::string_view format_str, Item item) {
...
@@ -20,71 +20,67 @@ void invoke_inner(fmt::string_view format_str, Item item) {
}
}
}
}
//
Item is the underlying type for duration (int, long, etc.)
//
Rep is a duration's representation type.
template
<
typename
Item
>
template
<
typename
Rep
>
void
invoke_outer
(
const
uint8_t
*
data
,
size_t
size
,
int
scaling
)
{
void
invoke_outer
(
const
uint8_t
*
data
,
size_t
size
,
int
period
)
{
// Always use a fixed location of the data.
// Always use a fixed location of the data.
using
fmt_fuzzer
::
nfixed
;
static_assert
(
sizeof
(
Rep
)
<=
fixed_size
,
"fixed size is too small"
);
if
(
size
<=
fixed_size
+
1
)
return
;
static_assert
(
sizeof
(
Item
)
<=
nfixed
,
"fixed size is too small"
);
const
Rep
rep
=
assign_from_buf
<
Rep
>
(
data
);
if
(
size
<=
nfixed
+
1
)
return
;
data
+=
fixed_size
;
size
-=
fixed_size
;
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
data
);
// Fast forward.
data
+=
nfixed
;
size
-=
nfixed
;
// data is already allocated separately in libFuzzer so reading past the end
// data is already allocated separately in libFuzzer so reading past the end
// will most likely be detected anyway.
// will most likely be detected anyway.
const
auto
format_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
size
);
const
auto
format_str
=
fmt
::
string_view
(
as_chars
(
data
),
size
);
// yocto, zepto, zetta and yotta are not handled.
// yocto, zepto, zetta and yotta are not handled.
switch
(
scaling
)
{
switch
(
period
)
{
case
1
:
case
1
:
invoke_inner
<
Item
,
std
::
atto
>
(
format_str
,
item
);
invoke_inner
<
std
::
atto
>
(
format_str
,
rep
);
break
;
break
;
case
2
:
case
2
:
invoke_inner
<
Item
,
std
::
femto
>
(
format_str
,
item
);
invoke_inner
<
std
::
femto
>
(
format_str
,
rep
);
break
;
break
;
case
3
:
case
3
:
invoke_inner
<
Item
,
std
::
pico
>
(
format_str
,
item
);
invoke_inner
<
std
::
pico
>
(
format_str
,
rep
);
break
;
break
;
case
4
:
case
4
:
invoke_inner
<
Item
,
std
::
nano
>
(
format_str
,
item
);
invoke_inner
<
std
::
nano
>
(
format_str
,
rep
);
break
;
break
;
case
5
:
case
5
:
invoke_inner
<
Item
,
std
::
micro
>
(
format_str
,
item
);
invoke_inner
<
std
::
micro
>
(
format_str
,
rep
);
break
;
break
;
case
6
:
case
6
:
invoke_inner
<
Item
,
std
::
milli
>
(
format_str
,
item
);
invoke_inner
<
std
::
milli
>
(
format_str
,
rep
);
break
;
break
;
case
7
:
case
7
:
invoke_inner
<
Item
,
std
::
centi
>
(
format_str
,
item
);
invoke_inner
<
std
::
centi
>
(
format_str
,
rep
);
break
;
break
;
case
8
:
case
8
:
invoke_inner
<
Item
,
std
::
deci
>
(
format_str
,
item
);
invoke_inner
<
std
::
deci
>
(
format_str
,
rep
);
break
;
break
;
case
9
:
case
9
:
invoke_inner
<
Item
,
std
::
deca
>
(
format_str
,
item
);
invoke_inner
<
std
::
deca
>
(
format_str
,
rep
);
break
;
break
;
case
10
:
case
10
:
invoke_inner
<
Item
,
std
::
kilo
>
(
format_str
,
item
);
invoke_inner
<
std
::
kilo
>
(
format_str
,
rep
);
break
;
break
;
case
11
:
case
11
:
invoke_inner
<
Item
,
std
::
mega
>
(
format_str
,
item
);
invoke_inner
<
std
::
mega
>
(
format_str
,
rep
);
break
;
break
;
case
12
:
case
12
:
invoke_inner
<
Item
,
std
::
giga
>
(
format_str
,
item
);
invoke_inner
<
std
::
giga
>
(
format_str
,
rep
);
break
;
break
;
case
13
:
case
13
:
invoke_inner
<
Item
,
std
::
tera
>
(
format_str
,
item
);
invoke_inner
<
std
::
tera
>
(
format_str
,
rep
);
break
;
break
;
case
14
:
case
14
:
invoke_inner
<
Item
,
std
::
peta
>
(
format_str
,
item
);
invoke_inner
<
std
::
peta
>
(
format_str
,
rep
);
break
;
break
;
case
15
:
case
15
:
invoke_inner
<
Item
,
std
::
exa
>
(
format_str
,
item
);
invoke_inner
<
std
::
exa
>
(
format_str
,
rep
);
}
}
}
}
...
@@ -92,46 +88,46 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
...
@@ -92,46 +88,46 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if
(
size
<=
4
)
return
0
;
if
(
size
<=
4
)
return
0
;
const
auto
representation
=
data
[
0
];
const
auto
representation
=
data
[
0
];
const
auto
scaling
=
data
[
1
];
const
auto
period
=
data
[
1
];
data
+=
2
;
data
+=
2
;
size
-=
2
;
size
-=
2
;
switch
(
representation
)
{
switch
(
representation
)
{
case
1
:
case
1
:
invoke_outer
<
char
>
(
data
,
size
,
scaling
);
invoke_outer
<
char
>
(
data
,
size
,
period
);
break
;
break
;
case
2
:
case
2
:
invoke_outer
<
signed
char
>
(
data
,
size
,
scaling
);
invoke_outer
<
signed
char
>
(
data
,
size
,
period
);
break
;
break
;
case
3
:
case
3
:
invoke_outer
<
unsigned
char
>
(
data
,
size
,
scaling
);
invoke_outer
<
unsigned
char
>
(
data
,
size
,
period
);
break
;
break
;
case
4
:
case
4
:
invoke_outer
<
short
>
(
data
,
size
,
scaling
);
invoke_outer
<
short
>
(
data
,
size
,
period
);
break
;
break
;
case
5
:
case
5
:
invoke_outer
<
unsigned
short
>
(
data
,
size
,
scaling
);
invoke_outer
<
unsigned
short
>
(
data
,
size
,
period
);
break
;
break
;
case
6
:
case
6
:
invoke_outer
<
int
>
(
data
,
size
,
scaling
);
invoke_outer
<
int
>
(
data
,
size
,
period
);
break
;
break
;
case
7
:
case
7
:
invoke_outer
<
unsigned
int
>
(
data
,
size
,
scaling
);
invoke_outer
<
unsigned
int
>
(
data
,
size
,
period
);
break
;
break
;
case
8
:
case
8
:
invoke_outer
<
long
>
(
data
,
size
,
scaling
);
invoke_outer
<
long
>
(
data
,
size
,
period
);
break
;
break
;
case
9
:
case
9
:
invoke_outer
<
unsigned
long
>
(
data
,
size
,
scaling
);
invoke_outer
<
unsigned
long
>
(
data
,
size
,
period
);
break
;
break
;
case
10
:
case
10
:
invoke_outer
<
float
>
(
data
,
size
,
scaling
);
invoke_outer
<
float
>
(
data
,
size
,
period
);
break
;
break
;
case
11
:
case
11
:
invoke_outer
<
double
>
(
data
,
size
,
scaling
);
invoke_outer
<
double
>
(
data
,
size
,
period
);
break
;
break
;
case
12
:
case
12
:
invoke_outer
<
long
double
>
(
data
,
size
,
scaling
);
invoke_outer
<
long
double
>
(
data
,
size
,
period
);
break
;
break
;
default:
default:
break
;
break
;
...
...
test/fuzzing/fuzzer-common.h
View file @
82c4e223
...
@@ -6,6 +6,9 @@
...
@@ -6,6 +6,9 @@
#include <cstdint> // std::uint8_t
#include <cstdint> // std::uint8_t
#include <cstring> // memcpy
#include <cstring> // memcpy
#include <vector>
#include <fmt/core.h>
// One can format to either a string, or a buffer. The latter is faster, but
// One can format to either a string, or a buffer. The latter is faster, but
// one may be interested in formatting to a string instead to verify it works
// one may be interested in formatting to a string instead to verify it works
...
@@ -18,13 +21,11 @@
...
@@ -18,13 +21,11 @@
// the fuzzing.
// the fuzzing.
#define FMT_FUZZ_SEPARATE_ALLOCATION 1
#define FMT_FUZZ_SEPARATE_ALLOCATION 1
namespace
fmt_fuzzer
{
// The size of the largest possible type in use.
// The size of the largest possible type in use.
// To let the the fuzzer mutation be efficient at cross pollinating between
// To let the the fuzzer mutation be efficient at cross pollinating between
// different types, use a fixed size format. The same bit pattern, interpreted
// different types, use a fixed size format. The same bit pattern, interpreted
// as another type, is likely interesting.
// as another type, is likely interesting.
constexpr
auto
nfixed
=
16
;
constexpr
auto
fixed_size
=
16
;
// Casts data to a char pointer.
// Casts data to a char pointer.
template
<
typename
T
>
inline
const
char
*
as_chars
(
const
T
*
data
)
{
template
<
typename
T
>
inline
const
char
*
as_chars
(
const
T
*
data
)
{
...
@@ -38,17 +39,37 @@ template <typename T> inline const std::uint8_t* as_bytes(const T* data) {
...
@@ -38,17 +39,37 @@ template <typename T> inline const std::uint8_t* as_bytes(const T* data) {
// Blits bytes from data to form an (assumed trivially constructible) object
// Blits bytes from data to form an (assumed trivially constructible) object
// of type Item.
// of type Item.
template
<
class
Item
>
inline
Item
assign
FromB
uf
(
const
std
::
uint8_t
*
data
)
{
template
<
class
Item
>
inline
Item
assign
_from_b
uf
(
const
std
::
uint8_t
*
data
)
{
auto
item
=
Item
();
auto
item
=
Item
();
std
::
memcpy
(
&
item
,
data
,
sizeof
(
Item
));
std
::
memcpy
(
&
item
,
data
,
sizeof
(
Item
));
return
item
;
return
item
;
}
}
// Reads a boolean value by looking at the first byte from data.
// Reads a boolean value by looking at the first byte from data.
template
<
>
inline
bool
assign
FromB
uf
<
bool
>
(
const
std
::
uint8_t
*
data
)
{
template
<
>
inline
bool
assign
_from_b
uf
<
bool
>
(
const
std
::
uint8_t
*
data
)
{
return
*
data
!=
0
;
return
*
data
!=
0
;
}
}
}
// namespace fmt_fuzzer
struct
data_to_string
{
#if FMT_FUZZ_SEPARATE_ALLOCATION
std
::
vector
<
char
>
buffer
;
data_to_string
(
const
uint8_t
*
data
,
size_t
size
,
bool
add_terminator
=
false
)
:
buffer
(
size
+
(
add_terminator
?
1
:
0
))
{
std
::
memcpy
(
buffer
.
data
(),
data
,
size
);
}
fmt
::
string_view
get
()
const
{
return
{
buffer
.
data
(),
buffer
.
size
()};
}
#else
fmt
::
string_view
sv
;
data_to_string
(
const
uint8_t
*
data
,
size_t
size
,
bool
=
false
)
:
str
(
as_chars
(
data
),
size
)
{}
fmt
::
string_view
get
()
const
{
return
sv
;
}
#endif
const
char
*
data
()
const
{
return
get
().
data
();
}
};
#endif // FUZZER_COMMON_H
#endif // FUZZER_COMMON_H
test/fuzzing/main.cc
View file @
82c4e223
...
@@ -17,6 +17,6 @@ int main(int argc, char** argv) {
...
@@ -17,6 +17,6 @@ int main(int argc, char** argv) {
std
::
vector
<
char
>
buf
(
static_cast
<
size_t
>
(
size
));
std
::
vector
<
char
>
buf
(
static_cast
<
size_t
>
(
size
));
in
.
read
(
buf
.
data
(),
size
);
in
.
read
(
buf
.
data
(),
size
);
assert
(
in
.
gcount
()
==
size
);
assert
(
in
.
gcount
()
==
size
);
LLVMFuzzerTestOneInput
(
fmt_fuzzer
::
as_bytes
(
buf
.
data
()),
buf
.
size
());
LLVMFuzzerTestOneInput
(
as_bytes
(
buf
.
data
()),
buf
.
size
());
}
}
}
}
test/fuzzing/named-arg.cc
View file @
82c4e223
// Copyright (c) 2019, Paul Dreik
// Copyright (c) 2019, Paul Dreik
// For the license information refer to format.h.
// For the license information refer to format.h.
#include <fmt/chrono.h>
#include <cstdint>
#include <cstdint>
#include <type_traits>
#include <type_traits>
#include <vector>
#include <vector>
#include <fmt/chrono.h>
#include "fuzzer-common.h"
#include "fuzzer-common.h"
template
<
typename
Item1
>
template
<
typename
T
>
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
,
unsigned
int
argsize
)
{
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
,
unsigned
arg_name_size
)
{
static_assert
(
sizeof
(
Item1
)
<=
fmt_fuzzer
::
nfixed
,
"nfixed too small"
);
static_assert
(
sizeof
(
T
)
<=
fixed_size
,
"fixed_size too small"
);
if
(
size
<=
fmt_fuzzer
::
nfixed
)
return
;
if
(
size
<=
fixed_size
)
return
;
const
Item1
item1
=
fmt_fuzzer
::
assignFromBuf
<
Item1
>
(
data
);
const
T
value
=
assign_from_buf
<
T
>
(
data
);
data
+=
fixed_size
;
data
+=
fmt_fuzzer
::
nfixed
;
size
-=
fixed_size
;
size
-=
fmt_fuzzer
::
nfixed
;
// How many chars should be used for the argument name?
if
(
argsize
<=
0
||
argsize
>=
size
)
return
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
if
(
arg_name_size
<=
0
||
arg_name_size
>=
size
)
return
;
std
::
vector
<
char
>
argnamebuffer
(
argsize
+
1
);
data_to_string
arg_name
(
data
,
arg_name_size
,
true
);
std
::
memcpy
(
argnamebuffer
.
data
(),
data
,
argsize
);
data
+=
arg_name_size
;
auto
argname
=
argnamebuffer
.
data
();
size
-=
arg_name_size
;
#else
auto
argname
=
fmt_fuzzer
::
as_chars
(
data
);
#endif
data
+=
argsize
;
size
-=
argsize
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
std
::
vector
<
char
>
fmtstringbuffer
(
size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
data
,
size
);
auto
format_str
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
size
);
#else
auto
format_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
size
);
#endif
data_to_string
format_str
(
data
,
size
);
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
format_str
,
fmt
::
arg
(
argname
,
item1
));
std
::
string
message
=
fmt
::
format
(
format_str
.
get
(),
fmt
::
arg
(
arg_name
.
data
(),
value
));
#else
#else
fmt
::
memory_buffer
out
;
fmt
::
memory_buffer
out
;
fmt
::
format_to
(
out
,
format_str
,
fmt
::
arg
(
argname
,
item1
));
fmt
::
format_to
(
out
,
format_str
.
get
(),
fmt
::
arg
(
arg_name
.
data
(),
value
));
#endif
#endif
}
}
// For dynamic dispatching to an explicit instantiation.
// For dynamic dispatching to an explicit instantiation.
template
<
typename
Callback
>
void
invoke
(
int
index
,
Callback
callback
)
{
template
<
typename
Callback
>
void
invoke
(
int
type
,
Callback
callback
)
{
switch
(
index
)
{
switch
(
type
)
{
case
0
:
case
0
:
callback
(
bool
());
callback
(
bool
());
break
;
break
;
...
@@ -100,14 +86,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
...
@@ -100,14 +86,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if
(
size
<=
3
)
return
0
;
if
(
size
<=
3
)
return
0
;
// Switch types depending on the first byte of the input.
// Switch types depending on the first byte of the input.
const
auto
first
=
data
[
0
]
&
0x0F
;
const
auto
type
=
data
[
0
]
&
0x0F
;
const
unsigned
second
=
(
data
[
0
]
&
0xF0
)
>>
4
;
const
unsigned
arg_name_size
=
(
data
[
0
]
&
0xF0
)
>>
4
;
data
++
;
data
++
;
size
--
;
size
--
;
try
{
try
{
invoke
(
first
,
[
=
](
auto
param1
)
{
invoke
(
type
,
[
=
](
auto
arg
)
{
invoke_fmt
<
decltype
(
param1
)
>
(
data
,
size
,
second
);
invoke_fmt
<
decltype
(
arg
)
>
(
data
,
size
,
arg_name_size
);
});
});
}
catch
(
std
::
exception
&
)
{
}
catch
(
std
::
exception
&
)
{
}
}
...
...
test/fuzzing/one-arg.cc
View file @
82c4e223
...
@@ -2,63 +2,35 @@
...
@@ -2,63 +2,35 @@
// For the license information refer to format.h.
// For the license information refer to format.h.
#include <cstdint>
#include <cstdint>
#include <stdexcept>
#include <exception>
#include <type_traits>
#include <vector>
#include <fmt/chrono.h>
#include <fmt/chrono.h>
#include "fuzzer-common.h"
#include "fuzzer-common.h"
using
fmt_fuzzer
::
nfixed
;
template
<
typename
T
,
typename
Repr
>
const
T
*
from_repr
(
const
Repr
&
r
)
{
return
&
r
;
}
template
<
typename
Item
>
template
<
>
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
)
{
const
std
::
tm
*
from_repr
<
std
::
tm
>
(
const
std
::
time_t
&
t
)
{
constexpr
auto
N
=
sizeof
(
Item
);
return
std
::
localtime
(
&
t
);
static_assert
(
N
<=
nfixed
,
"Nfixed is too small"
);
if
(
size
<=
nfixed
)
return
;
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
data
);
data
+=
nfixed
;
size
-=
nfixed
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
std
::
vector
<
char
>
fmtstringbuffer
(
size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
data
,
size
);
auto
format_str
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
size
);
#else
auto
format_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
size
);
#endif
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
format_str
,
item
);
#else
fmt
::
memory_buffer
message
;
fmt
::
format_to
(
message
,
format_str
,
item
);
#endif
}
}
void
invoke_fmt_time
(
const
uint8_t
*
data
,
size_t
size
)
{
template
<
typename
T
,
typename
Repr
=
T
>
using
Item
=
std
::
time_t
;
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
)
{
static_assert
(
sizeof
(
Item
)
<=
nfixed
,
"Nfixed too small"
);
static_assert
(
sizeof
(
Repr
)
<=
fixed_size
,
"Nfixed is too small"
);
if
(
size
<=
nfixed
)
return
;
if
(
size
<=
fixed_size
)
return
;
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
data
);
auto
repr
=
assign_from_buf
<
Repr
>
(
data
);
data
+=
nfixed
;
const
T
*
value
=
from_repr
<
T
>
(
repr
);
size
-=
nfixed
;
if
(
!
value
)
return
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
data
+=
fixed_size
;
std
::
vector
<
char
>
fmtstringbuffer
(
size
);
size
-=
fixed_size
;
std
::
memcpy
(
fmtstringbuffer
.
data
(),
data
,
size
);
data_to_string
format_str
(
data
,
size
);
auto
format_str
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
size
);
#else
auto
format_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
size
);
#endif
auto
*
b
=
std
::
localtime
(
&
item
);
if
(
b
)
{
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
format_str
,
*
b
);
std
::
string
message
=
fmt
::
format
(
format_str
.
get
(),
*
value
);
#else
#else
fmt
::
memory_buffer
message
;
fmt
::
memory_buffer
message
;
fmt
::
format_to
(
message
,
format_str
,
*
b
);
fmt
::
format_to
(
message
,
format_str
.
get
(),
*
value
);
#endif
#endif
}
}
}
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
)
{
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
)
{
...
@@ -110,7 +82,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
...
@@ -110,7 +82,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
invoke_fmt
<
long
double
>
(
data
,
size
);
invoke_fmt
<
long
double
>
(
data
,
size
);
break
;
break
;
case
13
:
case
13
:
invoke_fmt
_time
(
data
,
size
);
invoke_fmt
<
std
::
tm
,
std
::
time_t
>
(
data
,
size
);
break
;
break
;
default:
default:
break
;
break
;
...
...
test/fuzzing/two-args.cc
View file @
82c4e223
...
@@ -10,21 +10,19 @@
...
@@ -10,21 +10,19 @@
template
<
typename
Item1
,
typename
Item2
>
template
<
typename
Item1
,
typename
Item2
>
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
)
{
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
)
{
using
fmt_fuzzer
::
nfixed
;
static_assert
(
sizeof
(
Item1
)
<=
fixed_size
,
"size1 exceeded"
);
static_assert
(
sizeof
(
Item1
)
<=
nfixed
,
"size1 exceeded"
);
static_assert
(
sizeof
(
Item2
)
<=
fixed_size
,
"size2 exceeded"
);
static_assert
(
sizeof
(
Item2
)
<=
nfixed
,
"size2 exceeded"
);
if
(
size
<=
fixed_size
+
fixed_size
)
return
;
if
(
size
<=
nfixed
+
nfixed
)
return
;
const
Item1
item1
=
fmt_fuzzer
::
assignFromB
uf
<
Item1
>
(
data
);
const
Item1
item1
=
assign_from_b
uf
<
Item1
>
(
data
);
data
+=
nfixed
;
data
+=
fixed_size
;
size
-=
nfixed
;
size
-=
fixed_size
;
const
Item2
item2
=
fmt_fuzzer
::
assignFromBuf
<
Item2
>
(
data
);
const
Item2
item2
=
assign_from_buf
<
Item2
>
(
data
);
data
+=
nfixed
;
data
+=
fixed_size
;
size
-=
nfixed
;
size
-=
fixed_size
;
auto
format_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
size
);
auto
format_str
=
fmt
::
string_view
(
as_chars
(
data
),
size
);
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
format_str
,
item1
,
item2
);
std
::
string
message
=
fmt
::
format
(
format_str
,
item1
,
item2
);
#else
#else
...
@@ -91,13 +89,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
...
@@ -91,13 +89,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if
(
size
<=
3
)
return
0
;
if
(
size
<=
3
)
return
0
;
// Switch types depending on the first byte of the input.
// Switch types depending on the first byte of the input.
const
auto
first
=
data
[
0
]
&
0x0F
;
const
auto
type1
=
data
[
0
]
&
0x0F
;
const
auto
second
=
(
data
[
0
]
&
0xF0
)
>>
4
;
const
auto
type2
=
(
data
[
0
]
&
0xF0
)
>>
4
;
data
++
;
data
++
;
size
--
;
size
--
;
try
{
try
{
invoke
(
first
,
[
=
](
auto
param1
)
{
invoke
(
type1
,
[
=
](
auto
param1
)
{
invoke
(
second
,
[
=
](
auto
param2
)
{
invoke
(
type2
,
[
=
](
auto
param2
)
{
invoke_fmt
<
decltype
(
param1
),
decltype
(
param2
)
>
(
data
,
size
);
invoke_fmt
<
decltype
(
param1
),
decltype
(
param2
)
>
(
data
,
size
);
});
});
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment