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
7e56b6b6
Commit
7e56b6b6
authored
Oct 11, 2020
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix coding style and remove duplicate fuzzer
parent
41d97e1e
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
245 additions
and
411 deletions
+245
-411
test/fuzzing/CMakeLists.txt
test/fuzzing/CMakeLists.txt
+0
-1
test/fuzzing/build.sh
test/fuzzing/build.sh
+9
-9
test/fuzzing/chrono_duration.cpp
test/fuzzing/chrono_duration.cpp
+54
-66
test/fuzzing/fuzzer_common.h
test/fuzzing/fuzzer_common.h
+28
-41
test/fuzzing/main.cpp
test/fuzzing/main.cpp
+9
-8
test/fuzzing/named_arg.cpp
test/fuzzing/named_arg.cpp
+47
-60
test/fuzzing/one_arg.cpp
test/fuzzing/one_arg.cpp
+47
-55
test/fuzzing/sprintf.cpp
test/fuzzing/sprintf.cpp
+0
-116
test/fuzzing/two_args.cpp
test/fuzzing/two_args.cpp
+51
-55
No files found.
test/fuzzing/CMakeLists.txt
View file @
7e56b6b6
...
@@ -15,7 +15,6 @@ set(SOURCES
...
@@ -15,7 +15,6 @@ set(SOURCES
chrono_duration.cpp
chrono_duration.cpp
named_arg.cpp
named_arg.cpp
one_arg.cpp
one_arg.cpp
sprintf.cpp
two_args.cpp
two_args.cpp
)
)
...
...
test/fuzzing/build.sh
View file @
7e56b6b6
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
#
#
# Copyright (c) 2019 Paul Dreik
# Copyright (c) 2019 Paul Dreik
#
#
#
License: see LICENSE.rst in the fmt root directory
#
For the license information refer to format.h.
set
-e
set
-e
me
=
$(
basename
$0
)
me
=
$(
basename
$0
)
...
@@ -23,8 +23,8 @@ here=$(pwd)
...
@@ -23,8 +23,8 @@ here=$(pwd)
CXXFLAGSALL
=
"-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION= -g"
CXXFLAGSALL
=
"-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION= -g"
CMAKEFLAGSALL
=
"
$root
-GNinja -DCMAKE_BUILD_TYPE=Debug -DFMT_DOC=Off -DFMT_TEST=Off -DFMT_FUZZ=On -DCMAKE_CXX_STANDARD=17"
CMAKEFLAGSALL
=
"
$root
-GNinja -DCMAKE_BUILD_TYPE=Debug -DFMT_DOC=Off -DFMT_TEST=Off -DFMT_FUZZ=On -DCMAKE_CXX_STANDARD=17"
#
b
uilds the fuzzers as one would do if using afl or just making
#
B
uilds the fuzzers as one would do if using afl or just making
#binaries for reproducing.
#
binaries for reproducing.
builddir
=
$here
/build-fuzzers-reproduce
builddir
=
$here
/build-fuzzers-reproduce
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
@@ -32,7 +32,7 @@ CXX="ccache g++" CXXFLAGS="$CXXFLAGSALL" cmake \
...
@@ -32,7 +32,7 @@ CXX="ccache g++" CXXFLAGS="$CXXFLAGSALL" cmake \
$CMAKEFLAGSALL
$CMAKEFLAGSALL
cmake
--build
$builddir
cmake
--build
$builddir
#
for performance analysis of the fuzzers
#
For performance analysis of the fuzzers.
builddir
=
$here
/build-fuzzers-perfanalysis
builddir
=
$here
/build-fuzzers-perfanalysis
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
@@ -43,7 +43,7 @@ $CMAKEFLAGSALL \
...
@@ -43,7 +43,7 @@ $CMAKEFLAGSALL \
cmake
--build
$builddir
cmake
--build
$builddir
#
builds the fuzzers as oss-fuzz does
#
Builds the fuzzers as oss-fuzz does.
builddir
=
$here
/build-fuzzers-ossfuzz
builddir
=
$here
/build-fuzzers-ossfuzz
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
@@ -56,7 +56,7 @@ cmake $CMAKEFLAGSALL \
...
@@ -56,7 +56,7 @@ cmake $CMAKEFLAGSALL \
cmake
--build
$builddir
cmake
--build
$builddir
#
builds fuzzers for local fuzzing with libfuzzer with asan+usan
#
Builds fuzzers for local fuzzing with libfuzzer with asan+usan.
builddir
=
$here
/build-fuzzers-libfuzzer
builddir
=
$here
/build-fuzzers-libfuzzer
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
@@ -68,7 +68,7 @@ cmake $CMAKEFLAGSALL \
...
@@ -68,7 +68,7 @@ cmake $CMAKEFLAGSALL \
cmake
--build
$builddir
cmake
--build
$builddir
#
builds fuzzers for local fuzzing with libfuzzer with asan only
#
Builds fuzzers for local fuzzing with libfuzzer with asan only.
builddir
=
$here
/build-fuzzers-libfuzzer-addr
builddir
=
$here
/build-fuzzers-libfuzzer-addr
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
@@ -80,7 +80,7 @@ cmake $CMAKEFLAGSALL \
...
@@ -80,7 +80,7 @@ cmake $CMAKEFLAGSALL \
cmake
--build
$builddir
cmake
--build
$builddir
#
builds a fast fuzzer for making coverage fast
#
Builds a fast fuzzer for making coverage fast.
builddir
=
$here
/build-fuzzers-fast
builddir
=
$here
/build-fuzzers-fast
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
@@ -94,7 +94,7 @@ cmake $CMAKEFLAGSALL \
...
@@ -94,7 +94,7 @@ cmake $CMAKEFLAGSALL \
cmake
--build
$builddir
cmake
--build
$builddir
#
builds fuzzers for local fuzzing with afl
#
Builds fuzzers for local fuzzing with afl.
builddir
=
$here
/build-fuzzers-afl
builddir
=
$here
/build-fuzzers-afl
mkdir
-p
$builddir
mkdir
-p
$builddir
cd
$builddir
cd
$builddir
...
...
test/fuzzing/chrono_duration.cpp
View file @
7e56b6b6
// Copyright (c) 2019, Paul Dreik
// Copyright (c) 2019, Paul Dreik
//
License: see LICENSE.rst in the fmt root directory
//
For the license information refer to format.h.
#include <fmt/chrono.h>
#include <cstdint>
#include <cstdint>
#include <limits>
#include <fmt/chrono.h>
#include <stdexcept>
#include <type_traits>
#include <vector>
#include "fuzzer_common.h"
#include "fuzzer_common.h"
template
<
typename
Item
,
typename
Ratio
>
template
<
typename
Item
,
typename
Ratio
>
void
invoke_inner
(
fmt
::
string_view
format
string
,
const
Item
item
)
{
void
invoke_inner
(
fmt
::
string_view
format
_str
,
const
Item
item
)
{
const
std
::
chrono
::
duration
<
Item
,
Ratio
>
value
(
item
);
const
std
::
chrono
::
duration
<
Item
,
Ratio
>
value
(
item
);
try
{
try
{
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
format
string
,
value
);
std
::
string
message
=
fmt
::
format
(
format
_str
,
value
);
#else
#else
fmt
::
memory_buffer
buf
;
fmt
::
memory_buffer
buf
;
fmt
::
format_to
(
buf
,
format
string
,
value
);
fmt
::
format_to
(
buf
,
format
_str
,
value
);
#endif
#endif
}
catch
(
std
::
exception
&
/*e*/
)
{
}
catch
(
std
::
exception
&
)
{
}
}
}
}
// Item is the underlying type for duration (int, long
etc
)
// Item is the underlying type for duration (int, long
, etc.
)
template
<
typename
Item
>
template
<
typename
Item
>
void
invoke_outer
(
const
uint8_t
*
Data
,
size_t
Size
,
const
int
scaling
)
{
void
invoke_outer
(
const
uint8_t
*
data
,
size_t
size
,
int
scaling
)
{
//
always use a fixed location of the data
//
Always use a fixed location of the data.
using
fmt_fuzzer
::
N
fixed
;
using
fmt_fuzzer
::
n
fixed
;
constexpr
auto
N
=
sizeof
(
Item
);
static_assert
(
sizeof
(
Item
)
<=
nfixed
,
"fixed size is too small"
);
static_assert
(
N
<=
Nfixed
,
"fixed size is too small"
);
if
(
size
<=
nfixed
+
1
)
return
;
if
(
Size
<=
Nfixed
+
1
)
{
return
;
}
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
D
ata
);
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
d
ata
);
//
fast forward
//
Fast forward.
Data
+=
N
fixed
;
data
+=
n
fixed
;
Size
-=
N
fixed
;
size
-=
n
fixed
;
//
Data is already allocated separately in libFuzzer so reading past
//
data is already allocated separately in libFuzzer so reading past the end
//
the end will most likely be detected anyway
//
will most likely be detected anyway.
const
auto
format
string
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
Data
),
S
ize
);
const
auto
format
_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
s
ize
);
// doit_impl<Item,std::yocto>(buf.data(),item);
// yocto, zepto, zetta and yotta are not handled.
// doit_impl<Item,std::zepto>(buf.data(),item);
switch
(
scaling
)
{
switch
(
scaling
)
{
case
1
:
case
1
:
invoke_inner
<
Item
,
std
::
atto
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
atto
>
(
format
_str
,
item
);
break
;
break
;
case
2
:
case
2
:
invoke_inner
<
Item
,
std
::
femto
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
femto
>
(
format
_str
,
item
);
break
;
break
;
case
3
:
case
3
:
invoke_inner
<
Item
,
std
::
pico
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
pico
>
(
format
_str
,
item
);
break
;
break
;
case
4
:
case
4
:
invoke_inner
<
Item
,
std
::
nano
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
nano
>
(
format
_str
,
item
);
break
;
break
;
case
5
:
case
5
:
invoke_inner
<
Item
,
std
::
micro
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
micro
>
(
format
_str
,
item
);
break
;
break
;
case
6
:
case
6
:
invoke_inner
<
Item
,
std
::
milli
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
milli
>
(
format
_str
,
item
);
break
;
break
;
case
7
:
case
7
:
invoke_inner
<
Item
,
std
::
centi
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
centi
>
(
format
_str
,
item
);
break
;
break
;
case
8
:
case
8
:
invoke_inner
<
Item
,
std
::
deci
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
deci
>
(
format
_str
,
item
);
break
;
break
;
case
9
:
case
9
:
invoke_inner
<
Item
,
std
::
deca
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
deca
>
(
format
_str
,
item
);
break
;
break
;
case
10
:
case
10
:
invoke_inner
<
Item
,
std
::
kilo
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
kilo
>
(
format
_str
,
item
);
break
;
break
;
case
11
:
case
11
:
invoke_inner
<
Item
,
std
::
mega
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
mega
>
(
format
_str
,
item
);
break
;
break
;
case
12
:
case
12
:
invoke_inner
<
Item
,
std
::
giga
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
giga
>
(
format
_str
,
item
);
break
;
break
;
case
13
:
case
13
:
invoke_inner
<
Item
,
std
::
tera
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
tera
>
(
format
_str
,
item
);
break
;
break
;
case
14
:
case
14
:
invoke_inner
<
Item
,
std
::
peta
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
peta
>
(
format
_str
,
item
);
break
;
break
;
case
15
:
case
15
:
invoke_inner
<
Item
,
std
::
exa
>
(
format
string
,
item
);
invoke_inner
<
Item
,
std
::
exa
>
(
format
_str
,
item
);
}
}
// doit_impl<Item,std::zeta>(buf.data(),item);
// doit_impl<Item,std::yotta>(buf.data(),item);
}
}
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
Data
,
size_t
Size
)
{
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
)
{
if
(
Size
<=
4
)
{
if
(
size
<=
4
)
return
0
;
return
0
;
}
const
auto
representation
=
D
ata
[
0
];
const
auto
representation
=
d
ata
[
0
];
const
auto
scaling
=
D
ata
[
1
];
const
auto
scaling
=
d
ata
[
1
];
D
ata
+=
2
;
d
ata
+=
2
;
S
ize
-=
2
;
s
ize
-=
2
;
switch
(
representation
)
{
switch
(
representation
)
{
case
1
:
case
1
:
invoke_outer
<
char
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
char
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
2
:
case
2
:
invoke_outer
<
unsigned
char
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
signed
char
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
3
:
case
3
:
invoke_outer
<
signed
char
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
unsigned
char
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
4
:
case
4
:
invoke_outer
<
short
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
short
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
5
:
case
5
:
invoke_outer
<
unsigned
short
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
unsigned
short
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
6
:
case
6
:
invoke_outer
<
int
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
int
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
7
:
case
7
:
invoke_outer
<
unsigned
int
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
unsigned
int
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
8
:
case
8
:
invoke_outer
<
long
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
long
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
9
:
case
9
:
invoke_outer
<
unsigned
long
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
unsigned
long
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
10
:
case
10
:
invoke_outer
<
float
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
float
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
11
:
case
11
:
invoke_outer
<
double
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
double
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
case
12
:
case
12
:
invoke_outer
<
long
double
>
(
Data
,
S
ize
,
scaling
);
invoke_outer
<
long
double
>
(
data
,
s
ize
,
scaling
);
break
;
break
;
default:
default:
break
;
break
;
}
}
return
0
;
return
0
;
}
}
test/fuzzing/fuzzer_common.h
View file @
7e56b6b6
// Copyright (c) 2019, Paul Dreik
// For the license information refer to format.h.
#ifndef FUZZER_COMMON_H
#ifndef FUZZER_COMMON_H
#define FUZZER_COMMON_H
#define FUZZER_COMMON_H
// Copyright (c) 2019, Paul Dreik
// License: see LICENSE.rst in the fmt root directory
#include <cstdint> // std::uint8_t
#include <cstdint> // std::uint8_t
#include <cstring> // memcpy
#include <cstring> // memcpy
#include <type_traits> // trivially copyable
//
one can format to either a string, or a buf. buf is faster,
//
One can format to either a string, or a buffer. The latter is faster, but
//
but one may be interested in formatting to a string instead to
//
one may be interested in formatting to a string instead to verify it works
//
verify it works as intended. to avoid a combinatoric explosion,
//
as intended. To avoid a combinatoric explosion, select this at compile time
//
select this at compile time instead of dynamically from the fuzz data
//
instead of dynamically from the fuzz data.
#define FMT_FUZZ_FORMAT_TO_STRING 0
#define FMT_FUZZ_FORMAT_TO_STRING 0
//
if fmt is given a buffer that is separately allocated,
//
If {fmt} is given a buffer that is separately allocated, chances that address
//
chances that address sanitizer detects out of bound reads is
//
sanitizer detects out of bound reads is much higher. However, it slows down
//
much higher. However, it slows down
the fuzzing.
// the fuzzing.
#define FMT_FUZZ_SEPARATE_ALLOCATION 1
#define FMT_FUZZ_SEPARATE_ALLOCATION 1
// To let the the fuzzer mutation be efficient at cross pollinating
// between different types, use a fixed size format.
// The same bit pattern, interpreted as another type,
// is likely interesting.
// For this, we must know the size of the largest possible type in use.
// There are some problems on travis, claiming Nfixed is not a constant
// expression which seems to be an issue with older versions of libstdc++
#if _GLIBCXX_RELEASE >= 7
# include <algorithm>
namespace
fmt_fuzzer
{
namespace
fmt_fuzzer
{
constexpr
auto
Nfixed
=
std
::
max
(
sizeof
(
long
double
),
sizeof
(
std
::
intmax_t
));
}
#else
namespace
fmt_fuzzer
{
constexpr
auto
Nfixed
=
16
;
}
#endif
namespace
fmt_fuzzer
{
// The size of the largest possible type in use.
// view data as a c char pointer.
// To let the the fuzzer mutation be efficient at cross pollinating between
// different types, use a fixed size format. The same bit pattern, interpreted
// as another type, is likely interesting.
constexpr
auto
nfixed
=
16
;
// 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
)
{
return
static_cast
<
const
char
*>
(
static_cast
<
const
void
*>
(
data
)
);
return
reinterpret_cast
<
const
char
*>
(
data
);
}
}
//
view data as a byte pointer
//
Casts data to a byte pointer.
template
<
typename
T
>
inline
const
std
::
uint8_t
*
as_bytes
(
const
T
*
data
)
{
template
<
typename
T
>
inline
const
std
::
uint8_t
*
as_bytes
(
const
T
*
data
)
{
return
static_cast
<
const
std
::
uint8_t
*>
(
static_cast
<
const
void
*>
(
data
)
);
return
reinterpret_cast
<
const
std
::
uint8_t
*>
(
data
);
}
}
//
blits bytes from D
ata to form an (assumed trivially constructible) object
//
Blits bytes from d
ata to form an (assumed trivially constructible) object
// of type Item
// of type Item
.
template
<
class
Item
>
inline
Item
assignFromBuf
(
const
std
::
uint8_t
*
D
ata
)
{
template
<
class
Item
>
inline
Item
assignFromBuf
(
const
std
::
uint8_t
*
d
ata
)
{
Item
item
{}
;
auto
item
=
Item
()
;
std
::
memcpy
(
&
item
,
D
ata
,
sizeof
(
Item
));
std
::
memcpy
(
&
item
,
d
ata
,
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
assignFromBuf
<
bool
>
(
const
std
::
uint8_t
*
D
ata
)
{
template
<
>
inline
bool
assignFromBuf
<
bool
>
(
const
std
::
uint8_t
*
d
ata
)
{
return
!!
Data
[
0
]
;
return
*
data
!=
0
;
}
}
}
// namespace fmt_fuzzer
}
// namespace fmt_fuzzer
...
...
test/fuzzing/main.cpp
View file @
7e56b6b6
#include <cassert>
#include <cassert>
#include <fstream>
#include <fstream>
#include <sstream>
#include <vector>
#include <vector>
#include "fuzzer_common.h"
#include "fuzzer_common.h"
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
Data
,
size_t
Size
);
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
);
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
**
argv
)
{
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
std
::
ifstream
in
(
argv
[
i
]);
std
::
ifstream
in
(
argv
[
i
]);
assert
(
in
);
assert
(
in
);
in
.
seekg
(
0
,
std
::
ios_base
::
end
);
in
.
seekg
(
0
,
std
::
ios_base
::
end
);
const
auto
pos
=
in
.
tellg
();
const
auto
size
=
in
.
tellg
();
assert
(
pos
>=
0
);
assert
(
size
>=
0
);
in
.
seekg
(
0
,
std
::
ios_base
::
beg
);
in
.
seekg
(
0
,
std
::
ios_base
::
beg
);
std
::
vector
<
char
>
buf
(
static_cast
<
size_t
>
(
pos
));
std
::
vector
<
char
>
buf
(
static_cast
<
size_t
>
(
size
));
in
.
read
(
buf
.
data
(),
s
tatic_cast
<
long
>
(
buf
.
size
())
);
in
.
read
(
buf
.
data
(),
s
ize
);
assert
(
in
.
gcount
()
==
pos
);
assert
(
in
.
gcount
()
==
size
);
LLVMFuzzerTestOneInput
(
fmt_fuzzer
::
as_bytes
(
buf
.
data
()),
buf
.
size
());
LLVMFuzzerTestOneInput
(
fmt_fuzzer
::
as_bytes
(
buf
.
data
()),
buf
.
size
());
}
}
}
}
test/fuzzing/named_arg.cpp
View file @
7e56b6b6
// Copyright (c) 2019, Paul Dreik
// Copyright (c) 2019, Paul Dreik
//
License: see LICENSE.rst in the fmt root directory
//
For the license information refer to format.h.
#include <fmt/chrono.h>
#include <fmt/core.h>
#include <cstdint>
#include <cstdint>
#include <stdexcept>
#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
Item1
>
void
invoke_fmt
(
const
uint8_t
*
Data
,
size_t
Size
,
unsigned
int
argsize
)
{
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
size
,
unsigned
int
argsize
)
{
constexpr
auto
N1
=
sizeof
(
Item1
);
static_assert
(
sizeof
(
Item1
)
<=
fmt_fuzzer
::
nfixed
,
"nfixed too small"
);
static_assert
(
N1
<=
fmt_fuzzer
::
Nfixed
,
"Nfixed too small"
);
if
(
size
<=
fmt_fuzzer
::
nfixed
)
return
;
if
(
Size
<=
fmt_fuzzer
::
Nfixed
)
{
const
Item1
item1
=
fmt_fuzzer
::
assignFromBuf
<
Item1
>
(
data
);
return
;
}
const
Item1
item1
=
fmt_fuzzer
::
assignFromBuf
<
Item1
>
(
Data
);
Data
+=
fmt_fuzzer
::
N
fixed
;
data
+=
fmt_fuzzer
::
n
fixed
;
Size
-=
fmt_fuzzer
::
N
fixed
;
size
-=
fmt_fuzzer
::
n
fixed
;
// how many chars should be used for the argument name?
// How many chars should be used for the argument name?
if
(
argsize
<=
0
||
argsize
>=
Size
)
{
if
(
argsize
<=
0
||
argsize
>=
size
)
return
;
return
;
}
// allocating buffers separately is slower, but increases chances
// of detecting memory errors
#if FMT_FUZZ_SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
std
::
vector
<
char
>
argnamebuffer
(
argsize
+
1
);
std
::
vector
<
char
>
argnamebuffer
(
argsize
+
1
);
std
::
memcpy
(
argnamebuffer
.
data
(),
D
ata
,
argsize
);
std
::
memcpy
(
argnamebuffer
.
data
(),
d
ata
,
argsize
);
auto
argname
=
argnamebuffer
.
data
();
auto
argname
=
argnamebuffer
.
data
();
#else
#else
auto
argname
=
fmt_fuzzer
::
as_chars
(
D
ata
);
auto
argname
=
fmt_fuzzer
::
as_chars
(
d
ata
);
#endif
#endif
D
ata
+=
argsize
;
d
ata
+=
argsize
;
S
ize
-=
argsize
;
s
ize
-=
argsize
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
// allocates as tight as possible, making it easier to catch buffer overruns.
std
::
vector
<
char
>
fmtstringbuffer
(
size
);
std
::
vector
<
char
>
fmtstringbuffer
(
Size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
data
,
size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
Data
,
Size
);
auto
format_str
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
size
);
auto
fmtstring
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
Size
);
#else
#else
auto
f
mtstring
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
Data
),
S
ize
);
auto
f
ormat_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
s
ize
);
#endif
#endif
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
f
mtstring
,
fmt
::
arg
(
argname
,
item1
));
std
::
string
message
=
fmt
::
format
(
f
ormat_str
,
fmt
::
arg
(
argname
,
item1
));
#else
#else
fmt
::
memory_buffer
out
buf
;
fmt
::
memory_buffer
out
;
fmt
::
format_to
(
out
buf
,
fmtstring
,
fmt
::
arg
(
argname
,
item1
));
fmt
::
format_to
(
out
,
format_str
,
fmt
::
arg
(
argname
,
item1
));
#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
index
,
Callback
callback
)
{
switch
(
index
)
{
switch
(
index
)
{
case
0
:
case
0
:
callback
(
bool
{}
);
callback
(
bool
()
);
break
;
break
;
case
1
:
case
1
:
callback
(
char
{}
);
callback
(
char
()
);
break
;
break
;
case
2
:
case
2
:
using
sc
=
signed
char
;
using
sc
=
signed
char
;
callback
(
sc
{}
);
callback
(
sc
()
);
break
;
break
;
case
3
:
case
3
:
using
uc
=
unsigned
char
;
using
uc
=
unsigned
char
;
callback
(
uc
{}
);
callback
(
uc
()
);
break
;
break
;
case
4
:
case
4
:
callback
(
short
{}
);
callback
(
short
()
);
break
;
break
;
case
5
:
case
5
:
using
us
=
unsigned
short
;
using
us
=
unsigned
short
;
callback
(
us
{}
);
callback
(
us
()
);
break
;
break
;
case
6
:
case
6
:
callback
(
int
{}
);
callback
(
int
()
);
break
;
break
;
case
7
:
case
7
:
callback
(
unsigned
{}
);
callback
(
unsigned
()
);
break
;
break
;
case
8
:
case
8
:
callback
(
long
{}
);
callback
(
long
()
);
break
;
break
;
case
9
:
case
9
:
using
ul
=
unsigned
long
;
using
ul
=
unsigned
long
;
callback
(
ul
{}
);
callback
(
ul
()
);
break
;
break
;
case
10
:
case
10
:
callback
(
float
{}
);
callback
(
float
()
);
break
;
break
;
case
11
:
case
11
:
callback
(
double
{}
);
callback
(
double
()
);
break
;
break
;
case
12
:
case
12
:
using
LD
=
long
double
;
using
LD
=
long
double
;
callback
(
LD
{}
);
callback
(
LD
()
);
break
;
break
;
}
}
}
}
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
Data
,
size_t
Size
)
{
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
)
{
if
(
Size
<=
3
)
{
if
(
size
<=
3
)
return
0
;
return
0
;
}
// switch types depending on the first byte of the input
const
auto
first
=
Data
[
0
]
&
0x0F
;
const
unsigned
int
second
=
(
Data
[
0
]
&
0xF0
)
>>
4
;
Data
++
;
Size
--
;
auto
outerfcn
=
[
=
](
auto
param1
)
{
// Switch types depending on the first byte of the input.
invoke_fmt
<
decltype
(
param1
)
>
(
Data
,
Size
,
second
);
const
auto
first
=
data
[
0
]
&
0x0F
;
};
const
unsigned
second
=
(
data
[
0
]
&
0xF0
)
>>
4
;
data
++
;
size
--
;
try
{
try
{
invoke
(
first
,
outerfcn
);
invoke
(
first
,
[
=
](
auto
param1
)
{
}
catch
(
std
::
exception
&
/*e*/
)
{
invoke_fmt
<
decltype
(
param1
)
>
(
data
,
size
,
second
);
});
}
catch
(
std
::
exception
&
)
{
}
}
return
0
;
return
0
;
}
}
test/fuzzing/one_arg.cpp
View file @
7e56b6b6
// Copyright (c) 2019, Paul Dreik
// Copyright (c) 2019, Paul Dreik
//
License: see LICENSE.rst in the fmt root directory
//
For the license information refer to format.h.
#include <fmt/core.h>
#include <cstdint>
#include <cstdint>
#include <stdexcept>
#include <stdexcept>
#include <type_traits>
#include <type_traits>
#include <vector>
#include <vector>
#include <fmt/chrono.h>
#include <fmt/chrono.h>
#include "fuzzer_common.h"
#include "fuzzer_common.h"
using
fmt_fuzzer
::
N
fixed
;
using
fmt_fuzzer
::
n
fixed
;
template
<
typename
Item
>
template
<
typename
Item
>
void
invoke_fmt
(
const
uint8_t
*
Data
,
size_t
S
ize
)
{
void
invoke_fmt
(
const
uint8_t
*
data
,
size_t
s
ize
)
{
constexpr
auto
N
=
sizeof
(
Item
);
constexpr
auto
N
=
sizeof
(
Item
);
static_assert
(
N
<=
N
fixed
,
"Nfixed is too small"
);
static_assert
(
N
<=
n
fixed
,
"Nfixed is too small"
);
if
(
Size
<=
N
fixed
)
{
if
(
size
<=
n
fixed
)
{
return
;
return
;
}
}
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
D
ata
);
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
d
ata
);
Data
+=
N
fixed
;
data
+=
n
fixed
;
Size
-=
N
fixed
;
size
-=
n
fixed
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
// allocates as tight as possible, making it easier to catch buffer overruns.
std
::
vector
<
char
>
fmtstringbuffer
(
size
);
std
::
vector
<
char
>
fmtstringbuffer
(
Size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
data
,
size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
Data
,
Size
);
auto
format_str
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
size
);
auto
fmtstring
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
Size
);
#else
#else
auto
f
mtstring
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
Data
),
S
ize
);
auto
f
ormat_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
s
ize
);
#endif
#endif
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
f
mtstring
,
item
);
std
::
string
message
=
fmt
::
format
(
f
ormat_str
,
item
);
#else
#else
fmt
::
memory_buffer
message
;
fmt
::
memory_buffer
message
;
fmt
::
format_to
(
message
,
f
mtstring
,
item
);
fmt
::
format_to
(
message
,
f
ormat_str
,
item
);
#endif
#endif
}
}
void
invoke_fmt_time
(
const
uint8_t
*
Data
,
size_t
S
ize
)
{
void
invoke_fmt_time
(
const
uint8_t
*
data
,
size_t
s
ize
)
{
using
Item
=
std
::
time_t
;
using
Item
=
std
::
time_t
;
constexpr
auto
N
=
sizeof
(
Item
);
static_assert
(
sizeof
(
Item
)
<=
nfixed
,
"Nfixed too small"
);
static_assert
(
N
<=
Nfixed
,
"Nfixed too small"
);
if
(
size
<=
nfixed
)
return
;
if
(
Size
<=
Nfixed
)
{
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
data
);
return
;
data
+=
nfixed
;
}
size
-=
nfixed
;
const
Item
item
=
fmt_fuzzer
::
assignFromBuf
<
Item
>
(
Data
);
Data
+=
Nfixed
;
Size
-=
Nfixed
;
#if FMT_FUZZ_SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
// allocates as tight as possible, making it easier to catch buffer overruns.
std
::
vector
<
char
>
fmtstringbuffer
(
size
);
std
::
vector
<
char
>
fmtstringbuffer
(
Size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
data
,
size
);
std
::
memcpy
(
fmtstringbuffer
.
data
(),
Data
,
Size
);
auto
format_str
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
size
);
auto
fmtstring
=
fmt
::
string_view
(
fmtstringbuffer
.
data
(),
Size
);
#else
#else
auto
f
mtstring
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
Data
),
S
ize
);
auto
f
ormat_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
s
ize
);
#endif
#endif
auto
*
b
=
std
::
localtime
(
&
item
);
auto
*
b
=
std
::
localtime
(
&
item
);
if
(
b
)
{
if
(
b
)
{
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
f
mtstring
,
*
b
);
std
::
string
message
=
fmt
::
format
(
f
ormat_str
,
*
b
);
#else
#else
fmt
::
memory_buffer
message
;
fmt
::
memory_buffer
message
;
fmt
::
format_to
(
message
,
f
mtstring
,
*
b
);
fmt
::
format_to
(
message
,
f
ormat_str
,
*
b
);
#endif
#endif
}
}
}
}
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
Data
,
size_t
Size
)
{
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
)
{
if
(
Size
<=
3
)
{
if
(
size
<=
3
)
return
0
;
return
0
;
}
const
auto
first
=
D
ata
[
0
];
const
auto
first
=
d
ata
[
0
];
D
ata
++
;
d
ata
++
;
S
ize
--
;
s
ize
--
;
try
{
try
{
switch
(
first
)
{
switch
(
first
)
{
case
0
:
case
0
:
invoke_fmt
<
bool
>
(
Data
,
S
ize
);
invoke_fmt
<
bool
>
(
data
,
s
ize
);
break
;
break
;
case
1
:
case
1
:
invoke_fmt
<
char
>
(
Data
,
S
ize
);
invoke_fmt
<
char
>
(
data
,
s
ize
);
break
;
break
;
case
2
:
case
2
:
invoke_fmt
<
unsigned
char
>
(
Data
,
S
ize
);
invoke_fmt
<
unsigned
char
>
(
data
,
s
ize
);
break
;
break
;
case
3
:
case
3
:
invoke_fmt
<
signed
char
>
(
Data
,
S
ize
);
invoke_fmt
<
signed
char
>
(
data
,
s
ize
);
break
;
break
;
case
4
:
case
4
:
invoke_fmt
<
short
>
(
Data
,
S
ize
);
invoke_fmt
<
short
>
(
data
,
s
ize
);
break
;
break
;
case
5
:
case
5
:
invoke_fmt
<
unsigned
short
>
(
Data
,
S
ize
);
invoke_fmt
<
unsigned
short
>
(
data
,
s
ize
);
break
;
break
;
case
6
:
case
6
:
invoke_fmt
<
int
>
(
Data
,
S
ize
);
invoke_fmt
<
int
>
(
data
,
s
ize
);
break
;
break
;
case
7
:
case
7
:
invoke_fmt
<
unsigned
int
>
(
Data
,
S
ize
);
invoke_fmt
<
unsigned
int
>
(
data
,
s
ize
);
break
;
break
;
case
8
:
case
8
:
invoke_fmt
<
long
>
(
Data
,
S
ize
);
invoke_fmt
<
long
>
(
data
,
s
ize
);
break
;
break
;
case
9
:
case
9
:
invoke_fmt
<
unsigned
long
>
(
Data
,
S
ize
);
invoke_fmt
<
unsigned
long
>
(
data
,
s
ize
);
break
;
break
;
case
10
:
case
10
:
invoke_fmt
<
float
>
(
Data
,
S
ize
);
invoke_fmt
<
float
>
(
data
,
s
ize
);
break
;
break
;
case
11
:
case
11
:
invoke_fmt
<
double
>
(
Data
,
S
ize
);
invoke_fmt
<
double
>
(
data
,
s
ize
);
break
;
break
;
case
12
:
case
12
:
invoke_fmt
<
long
double
>
(
Data
,
S
ize
);
invoke_fmt
<
long
double
>
(
data
,
s
ize
);
break
;
break
;
case
13
:
case
13
:
invoke_fmt_time
(
Data
,
S
ize
);
invoke_fmt_time
(
data
,
s
ize
);
break
;
break
;
default:
default:
break
;
break
;
}
}
}
catch
(
std
::
exception
&
/*e*/
)
{
}
catch
(
std
::
exception
&
)
{
}
}
return
0
;
return
0
;
}
}
test/fuzzing/sprintf.cpp
deleted
100644 → 0
View file @
41d97e1e
// Copyright (c) 2019, Paul Dreik
// License: see LICENSE.rst in the fmt root directory
#include <fmt/format.h>
#include <fmt/printf.h>
#include <cstdint>
#include <stdexcept>
#include "fuzzer_common.h"
using
fmt_fuzzer
::
Nfixed
;
template
<
typename
Item1
,
typename
Item2
>
void
invoke_fmt
(
const
uint8_t
*
Data
,
size_t
Size
)
{
constexpr
auto
N1
=
sizeof
(
Item1
);
constexpr
auto
N2
=
sizeof
(
Item2
);
static_assert
(
N1
<=
Nfixed
,
"size1 exceeded"
);
static_assert
(
N2
<=
Nfixed
,
"size2 exceeded"
);
if
(
Size
<=
Nfixed
+
Nfixed
)
{
return
;
}
Item1
item1
=
fmt_fuzzer
::
assignFromBuf
<
Item1
>
(
Data
);
Data
+=
Nfixed
;
Size
-=
Nfixed
;
Item2
item2
=
fmt_fuzzer
::
assignFromBuf
<
Item2
>
(
Data
);
Data
+=
Nfixed
;
Size
-=
Nfixed
;
auto
fmtstring
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
Data
),
Size
);
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
fmtstring
,
item1
,
item2
);
#else
fmt
::
memory_buffer
message
;
fmt
::
format_to
(
message
,
fmtstring
,
item1
,
item2
);
#endif
}
// for dynamic dispatching to an explicit instantiation
template
<
typename
Callback
>
void
invoke
(
int
index
,
Callback
callback
)
{
switch
(
index
)
{
case
0
:
callback
(
bool
{});
break
;
case
1
:
callback
(
char
{});
break
;
case
2
:
using
sc
=
signed
char
;
callback
(
sc
{});
break
;
case
3
:
using
uc
=
unsigned
char
;
callback
(
uc
{});
break
;
case
4
:
callback
(
short
{});
break
;
case
5
:
using
us
=
unsigned
short
;
callback
(
us
{});
break
;
case
6
:
callback
(
int
{});
break
;
case
7
:
callback
(
unsigned
{});
break
;
case
8
:
callback
(
long
{});
break
;
case
9
:
using
ul
=
unsigned
long
;
callback
(
ul
{});
break
;
case
10
:
callback
(
float
{});
break
;
case
11
:
callback
(
double
{});
break
;
case
12
:
using
LD
=
long
double
;
callback
(
LD
{});
break
;
case
13
:
using
ptr
=
void
*
;
callback
(
ptr
{});
break
;
}
}
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
Data
,
size_t
Size
)
{
if
(
Size
<=
3
)
{
return
0
;
}
// switch types depending on the first byte of the input
const
auto
first
=
Data
[
0
]
&
0x0F
;
const
auto
second
=
(
Data
[
0
]
&
0xF0
)
>>
4
;
Data
++
;
Size
--
;
auto
outer
=
[
=
](
auto
param1
)
{
auto
inner
=
[
=
](
auto
param2
)
{
invoke_fmt
<
decltype
(
param1
),
decltype
(
param2
)
>
(
Data
,
Size
);
};
invoke
(
second
,
inner
);
};
try
{
invoke
(
first
,
outer
);
}
catch
(
std
::
exception
&
/*e*/
)
{
}
return
0
;
}
test/fuzzing/two_args.cpp
View file @
7e56b6b6
// Copyright (c) 2019, Paul Dreik
// Copyright (c) 2019, Paul Dreik
//
License: see LICENSE.rst in the fmt root directory
//
For the license information refer to format.h.
#include <fmt/format.h>
#include <cstdint>
#include <cstdint>
#include <stdexcept>
#include <exception>
#include <type_traits>
#include <string>
#include <fmt/format.h>
#include "fuzzer_common.h"
#include "fuzzer_common.h"
constexpr
auto
Nfixed
=
fmt_fuzzer
::
N
fixed
;
constexpr
auto
nfixed
=
fmt_fuzzer
::
n
fixed
;
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
)
{
constexpr
auto
N1
=
sizeof
(
Item1
);
static_assert
(
sizeof
(
Item1
)
<=
nfixed
,
"size1 exceeded"
);
constexpr
auto
N2
=
sizeof
(
Item2
);
static_assert
(
sizeof
(
Item2
)
<=
nfixed
,
"size2 exceeded"
);
static_assert
(
N1
<=
Nfixed
,
"size1 exceeded"
);
if
(
size
<=
nfixed
+
nfixed
)
return
;
static_assert
(
N2
<=
Nfixed
,
"size2 exceeded"
);
if
(
Size
<=
Nfixed
+
Nfixed
)
{
const
Item1
item1
=
fmt_fuzzer
::
assignFromBuf
<
Item1
>
(
data
);
return
;
data
+=
nfixed
;
}
size
-=
nfixed
;
const
Item1
item1
=
fmt_fuzzer
::
assignFromBuf
<
Item1
>
(
Data
);
Data
+=
Nfixed
;
Size
-=
Nfixed
;
const
Item2
item2
=
fmt_fuzzer
::
assignFromBuf
<
Item2
>
(
D
ata
);
const
Item2
item2
=
fmt_fuzzer
::
assignFromBuf
<
Item2
>
(
d
ata
);
Data
+=
N
fixed
;
data
+=
n
fixed
;
Size
-=
N
fixed
;
size
-=
n
fixed
;
auto
f
mtstring
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
Data
),
S
ize
);
auto
f
ormat_str
=
fmt
::
string_view
(
fmt_fuzzer
::
as_chars
(
data
),
s
ize
);
#if FMT_FUZZ_FORMAT_TO_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std
::
string
message
=
fmt
::
format
(
f
mtstring
,
item1
,
item2
);
std
::
string
message
=
fmt
::
format
(
f
ormat_str
,
item1
,
item2
);
#else
#else
fmt
::
memory_buffer
message
;
fmt
::
memory_buffer
message
;
fmt
::
format_to
(
message
,
f
mtstring
,
item1
,
item2
);
fmt
::
format_to
(
message
,
f
ormat_str
,
item1
,
item2
);
#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
index
,
Callback
callback
)
{
switch
(
index
)
{
switch
(
index
)
{
case
0
:
case
0
:
callback
(
bool
{}
);
callback
(
bool
()
);
break
;
break
;
case
1
:
case
1
:
callback
(
char
{}
);
callback
(
char
()
);
break
;
break
;
case
2
:
case
2
:
using
sc
=
signed
char
;
using
sc
=
signed
char
;
callback
(
sc
{}
);
callback
(
sc
()
);
break
;
break
;
case
3
:
case
3
:
using
uc
=
unsigned
char
;
using
uc
=
unsigned
char
;
callback
(
uc
{}
);
callback
(
uc
()
);
break
;
break
;
case
4
:
case
4
:
callback
(
short
{}
);
callback
(
short
()
);
break
;
break
;
case
5
:
case
5
:
using
us
=
unsigned
short
;
using
us
=
unsigned
short
;
callback
(
us
{}
);
callback
(
us
()
);
break
;
break
;
case
6
:
case
6
:
callback
(
int
{}
);
callback
(
int
()
);
break
;
break
;
case
7
:
case
7
:
callback
(
unsigned
{}
);
callback
(
unsigned
()
);
break
;
break
;
case
8
:
case
8
:
callback
(
long
{}
);
callback
(
long
()
);
break
;
break
;
case
9
:
case
9
:
using
ul
=
unsigned
long
;
using
ul
=
unsigned
long
;
callback
(
ul
{}
);
callback
(
ul
()
);
break
;
break
;
case
10
:
case
10
:
callback
(
float
{}
);
callback
(
float
()
);
break
;
break
;
case
11
:
case
11
:
callback
(
double
{}
);
callback
(
double
()
);
break
;
break
;
case
12
:
case
12
:
using
LD
=
long
double
;
using
LD
=
long
double
;
callback
(
LD
{});
callback
(
LD
());
break
;
case
13
:
using
ptr
=
void
*
;
callback
(
ptr
());
break
;
break
;
}
}
}
}
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
Data
,
size_t
Size
)
{
extern
"C"
int
LLVMFuzzerTestOneInput
(
const
uint8_t
*
data
,
size_t
size
)
{
if
(
Size
<=
3
)
{
if
(
size
<=
3
)
return
0
;
return
0
;
}
// switch types depending on the first byte of the input
const
auto
first
=
Data
[
0
]
&
0x0F
;
const
auto
second
=
(
Data
[
0
]
&
0xF0
)
>>
4
;
Data
++
;
Size
--
;
auto
outer
=
[
=
](
auto
param1
)
{
auto
inner
=
[
=
](
auto
param2
)
{
invoke_fmt
<
decltype
(
param1
),
decltype
(
param2
)
>
(
Data
,
Size
);
};
invoke
(
second
,
inner
);
};
// Switch types depending on the first byte of the input.
const
auto
first
=
data
[
0
]
&
0x0F
;
const
auto
second
=
(
data
[
0
]
&
0xF0
)
>>
4
;
data
++
;
size
--
;
try
{
try
{
invoke
(
first
,
outer
);
invoke
(
first
,
[
=
](
auto
param1
)
{
}
catch
(
std
::
exception
&
/*e*/
)
{
invoke
(
second
,
[
=
](
auto
param2
)
{
invoke_fmt
<
decltype
(
param1
),
decltype
(
param2
)
>
(
data
,
size
);
});
});
}
catch
(
std
::
exception
&
)
{
}
}
return
0
;
return
0
;
}
}
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