diff --git a/fuzzing/Makefile b/fuzzing/Makefile index 3b02eb2..2a71f4f 100644 --- a/fuzzing/Makefile +++ b/fuzzing/Makefile @@ -22,6 +22,7 @@ oss-fuzz: # "Unit tests" $(CXX) $(CXXFLAGS) -std=c++17 -O3 Extensions.cpp -o $(OUT)/Extensions $(LIB_FUZZING_ENGINE) $(CXX) $(CXXFLAGS) -std=c++17 -O3 QueryParser.cpp -o $(OUT)/QueryParser $(LIB_FUZZING_ENGINE) + $(CXX) $(CXXFLAGS) -std=c++17 -O3 MultipartParser.cpp -o $(OUT)/MultipartParser $(LIB_FUZZING_ENGINE) $(CXX) $(CXXFLAGS) -std=c++17 -O3 WebSocket.cpp -o $(OUT)/WebSocket $(LIB_FUZZING_ENGINE) $(CXX) $(CXXFLAGS) -std=c++17 -O3 Http.cpp -o $(OUT)/Http $(LIB_FUZZING_ENGINE) $(CXX) $(CXXFLAGS) -DUWS_WITH_PROXY -std=c++17 -O3 Http.cpp -o $(OUT)/HttpWithProxy $(LIB_FUZZING_ENGINE) diff --git a/fuzzing/MultipartParser.cpp b/fuzzing/MultipartParser.cpp new file mode 100644 index 0000000..4dcc329 --- /dev/null +++ b/fuzzing/MultipartParser.cpp @@ -0,0 +1,62 @@ +/* This is a fuzz test of the multipart parser */ + +#define WIN32_EXPORT + +#include +#include +#include + +#include "../src/Multipart.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + if (!size) { + return 0; + } + + char *mutableMemory = (char *) malloc(size); + memcpy(mutableMemory, data, size); + + /* First byte determines how long contentType is */ + unsigned char contentTypeLength = data[0]; + size--; + + std::string_view contentType((char *) mutableMemory + 1, std::min(contentTypeLength, size)); + size -= contentType.length(); + + std::string_view body((char *) mutableMemory + 1 + contentType.length(), size); + + uWS::MultipartParser mp(contentType); + if (mp.isValid()) { + mp.setBody(body); + + std::pair headers[10]; + + while (true) { + std::optional optionalPart = mp.getNextPart(headers); + if (!optionalPart.has_value()) { + break; + } + + std::string_view part = optionalPart.value(); + + for (int i = 0; headers[i].first.length(); i++) { + /* We care about content-type and content-disposition */ + if (headers[i].first == "content-disposition") { + /* Parse the parameters */ + uWS::ParameterParser pp(headers[i].second); + while (true) { + auto [key, value] = pp.getKeyValue(); + if (!key.length()) { + break; + } + } + } + } + } + } + + free(mutableMemory); + return 0; +} +