mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-04-11 19:28:30 +00:00
Add two new fuzzers (#2412)
The goal is to increase code coverage by way of OSS-Fuzz. A recent code coverage report is available at https://storage.googleapis.com/oss-fuzz-coverage/cpp-httplib/reports/20260326/linux/report.html Signed-off-by: David Korczynski <david@adalogics.com>
This commit is contained in:
@@ -13,8 +13,10 @@ ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
|||||||
BROTLI_DIR = /usr/local/opt/brotli
|
BROTLI_DIR = /usr/local/opt/brotli
|
||||||
# BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
|
# BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
|
||||||
|
|
||||||
|
FUZZERS = server_fuzzer url_parser_fuzzer header_parser_fuzzer
|
||||||
|
|
||||||
# Runs all the tests and also fuzz tests against seed corpus.
|
# Runs all the tests and also fuzz tests against seed corpus.
|
||||||
all : server_fuzzer
|
all : $(FUZZERS)
|
||||||
./server_fuzzer corpus/*
|
./server_fuzzer corpus/*
|
||||||
|
|
||||||
# Fuzz target, so that you can choose which $(LIB_FUZZING_ENGINE) to use.
|
# Fuzz target, so that you can choose which $(LIB_FUZZING_ENGINE) to use.
|
||||||
@@ -23,5 +25,11 @@ server_fuzzer : server_fuzzer.cc ../../httplib.h
|
|||||||
$(CXX) $(CXXFLAGS) -o $@ $< $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread -lanl
|
$(CXX) $(CXXFLAGS) -o $@ $< $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread -lanl
|
||||||
zip -q -r server_fuzzer_seed_corpus.zip corpus
|
zip -q -r server_fuzzer_seed_corpus.zip corpus
|
||||||
|
|
||||||
|
header_parser_fuzzer : header_parser_fuzzer.cc ../../httplib.h
|
||||||
|
$(CXX) $(CXXFLAGS) -o $@ $< $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread -lanl
|
||||||
|
|
||||||
|
url_parser_fuzzer : url_parser_fuzzer.cc ../../httplib.h
|
||||||
|
$(CXX) $(CXXFLAGS) -o $@ $< $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread -lanl
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f server_fuzzer pem *.0 *.o *.1 *.srl *.zip
|
rm -f server_fuzzer pem *.0 *.o *.1 *.srl *.zip
|
||||||
|
|||||||
59
test/fuzzing/header_parser_fuzzer.cc
Normal file
59
test/fuzzing/header_parser_fuzzer.cc
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <httplib.h>
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
if (size < 2) return 0;
|
||||||
|
|
||||||
|
uint8_t selector = data[0];
|
||||||
|
const char *payload = reinterpret_cast<const char *>(data + 1);
|
||||||
|
size_t payload_size = size - 1;
|
||||||
|
std::string input(payload, payload_size);
|
||||||
|
|
||||||
|
switch (selector % 7) {
|
||||||
|
case 0: {
|
||||||
|
// parse_range_header
|
||||||
|
httplib::Ranges ranges;
|
||||||
|
httplib::detail::parse_range_header(input, ranges);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
// parse_accept_header
|
||||||
|
std::vector<std::string> content_types;
|
||||||
|
httplib::detail::parse_accept_header(input, content_types);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
// extract_media_type with params
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
httplib::detail::extract_media_type(input, ¶ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
// parse_multipart_boundary
|
||||||
|
std::string boundary;
|
||||||
|
httplib::detail::parse_multipart_boundary(input, boundary);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
// parse_disposition_params
|
||||||
|
httplib::Params params;
|
||||||
|
httplib::detail::parse_disposition_params(input, params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
// parse_http_date
|
||||||
|
httplib::detail::parse_http_date(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
// can_compress_content_type
|
||||||
|
httplib::detail::can_compress_content_type(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
52
test/fuzzing/url_parser_fuzzer.cc
Normal file
52
test/fuzzing/url_parser_fuzzer.cc
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <httplib.h>
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
if (size < 2) return 0;
|
||||||
|
|
||||||
|
// Use first byte to select which parsing function to exercise
|
||||||
|
uint8_t selector = data[0];
|
||||||
|
const char *payload = reinterpret_cast<const char *>(data + 1);
|
||||||
|
size_t payload_size = size - 1;
|
||||||
|
std::string input(payload, payload_size);
|
||||||
|
|
||||||
|
switch (selector % 6) {
|
||||||
|
case 0: {
|
||||||
|
// parse_query_text
|
||||||
|
httplib::Params params;
|
||||||
|
httplib::detail::parse_query_text(payload, payload_size, params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
// decode_query_component
|
||||||
|
httplib::decode_query_component(input, true);
|
||||||
|
httplib::decode_query_component(input, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
// decode_path_component
|
||||||
|
httplib::decode_path_component(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
// encode_query_component
|
||||||
|
httplib::encode_query_component(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
// normalize_query_string
|
||||||
|
httplib::detail::normalize_query_string(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
// is_valid_path
|
||||||
|
httplib::detail::is_valid_path(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user