Skip to content

Commit ffdc315

Browse files
committed
added fuzzing client [skip ci]
1 parent 740b2b9 commit ffdc315

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed

Makefile

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,32 @@ TEST_CPPFLAGS = -DSIMPLECPP_TEST_SOURCE_DIR=\"$(CURDIR)\"
1111
test.o: CPPFLAGS += $(TEST_CPPFLAGS)
1212

1313
%.o: %.cpp simplecpp.h
14-
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
14+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< $(LIB_FUZZING_ENGINE)
15+
16+
fuzz_no.o: fuzz.cpp
17+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DNO_FUZZ -c -o $@ fuzz.cpp
1518

1619
testrunner: test.o simplecpp.o
17-
$(CXX) $(LDFLAGS) simplecpp.o test.o -o testrunner
20+
$(CXX) $(LDFLAGS) -o $@ $^
1821

1922
test: testrunner simplecpp
2023
./testrunner
2124
python3 run-tests.py
2225
python3 -m pytest integration_test.py -vv
2326

27+
fuzz: fuzz.o simplecpp.o
28+
# TODO: use -stdlib=libc++ -lc++
29+
# make fuzz CXX=clang++ CXXOPTS="-O2 -fno-omit-frame-pointer -g -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize-address-use-after-scope -fno-sanitize=integer -fno-sanitize-recover=undefined" LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
30+
$(CXX) $(LDFLAGS) $(CXXFLAGS) -o $@ $^ $(LIB_FUZZING_ENGINE)
31+
32+
no-fuzz: fuzz_no.o simplecpp.o
33+
$(CXX) $(LDFLAGS) $(CXXFLAGS) -o $@ $^
34+
2435
selfcheck: simplecpp
2536
./selfcheck.sh
2637

2738
simplecpp: main.o simplecpp.o
28-
$(CXX) $(LDFLAGS) main.o simplecpp.o -o simplecpp
39+
$(CXX) $(LDFLAGS) -o $@ $^
2940

3041
clean:
31-
rm -f testrunner simplecpp *.o
42+
rm -f testrunner fuzz no-fuzz simplecpp *.o

fuzz.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* simplecpp - A simple and high-fidelity C/C++ preprocessor library
3+
* Copyright (C) 2016-2024 simplecpp team
4+
*/
5+
6+
#include "simplecpp.h"
7+
8+
#include <cstdint>
9+
10+
#ifdef NO_FUZZ
11+
#include <cstdlib>
12+
#include <fstream>
13+
#include <sstream>
14+
#include <string>
15+
#endif
16+
17+
static void doProcess(const uint8_t *data, size_t dataSize)
18+
{
19+
simplecpp::OutputList outputList;
20+
std::vector<std::string> files;
21+
simplecpp::TokenList rawtokens(data, dataSize, files, "test.cpp", &outputList);
22+
23+
simplecpp::TokenList outputTokens(files);
24+
simplecpp::FileDataCache filedata;
25+
const simplecpp::DUI dui;
26+
std::list<simplecpp::MacroUsage> macroUsage;
27+
std::list<simplecpp::IfCond> ifCond;
28+
simplecpp::preprocess(outputTokens, rawtokens, files, filedata, dui, &outputList, &macroUsage, &ifCond);
29+
30+
simplecpp::cleanup(filedata);
31+
}
32+
33+
#ifndef NO_FUZZ
34+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize);
35+
36+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize)
37+
{
38+
doProcess(data, dataSize);
39+
return 0;
40+
}
41+
#else
42+
int main(int argc, char * argv[])
43+
{
44+
if (argc < 2 || argc > 3)
45+
return EXIT_FAILURE;
46+
47+
std::ifstream f(argv[1]);
48+
if (!f.is_open())
49+
return EXIT_FAILURE;
50+
51+
std::ostringstream oss;
52+
oss << f.rdbuf();
53+
54+
if (!f.good())
55+
return EXIT_FAILURE;
56+
57+
const int cnt = (argc == 3) ? std::stoi(argv[2]) : 1;
58+
59+
const std::string code = oss.str();
60+
for (int i = 0; i < cnt; ++i)
61+
doProcess(reinterpret_cast<const uint8_t*>(code.data()), code.size());
62+
63+
return EXIT_SUCCESS;
64+
}
65+
#endif

0 commit comments

Comments
 (0)