diff --git a/CMakeLists.txt b/CMakeLists.txt
index 308dc9c0e..198044f30 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ set(CMAKE_ENABLE_EXPORTS TRUE)
option(CMAKE_INTERPROCEDURAL_OPTIMIZATION "Perform link time optimization" ON)
option(ENABLE_WARNING_ERROR "Consider compiler warnings to be errors" ON)
option(ENABLE_PROFILE_GUIDED_OPTIMIZATION "Perform profile guided optimization" OFF)
+option(ENABLE_FUZZ_TESTING "Enable building fuzzers and regression testing with libFuzzer" ON)
# preserve frame pointers for ease of debugging and profiling
# see https://fedoraproject.org/wiki/Changes/fno-omit-frame-pointer
diff --git a/pom.xml b/pom.xml
index 5a9fe3a32..5a4b9d082 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,6 +108,9 @@
share/index.html
scripts/git-clang-format
tests/nginx/**
+ tests/fuzz/fuzz_http2_decoder/**
+ tests/fuzz/fuzz_http1_decoder/**
+ **/README.md
diff --git a/run.py.in b/run.py.in
index 6b4b530d9..931385c47 100755
--- a/run.py.in
+++ b/run.py.in
@@ -70,6 +70,7 @@ env_vars = {
'PYTHONPATH': os.pathsep.join(python_path),
'PATH': os.pathsep.join(dedup(["${CMAKE_BINARY_DIR}",
os.path.join("${CMAKE_BINARY_DIR}", 'tests'),
+ os.path.join("${CMAKE_BINARY_DIR}", 'tests/fuzz'),
os.path.join("${CMAKE_BINARY_DIR}", 'router'),
os.path.join("${CMAKE_SOURCE_DIR}", 'tools'),
os.path.join("${CMAKE_BINARY_DIR}", 'tools'),
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 757c6f369..72c3beda8 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -246,3 +246,7 @@ add_subdirectory(cpp)
if(BUILD_BENCHMARKS)
add_subdirectory(c_benchmarks)
endif()
+
+if (ENABLE_FUZZ_TESTING)
+ add_subdirectory(fuzz)
+endif (ENABLE_FUZZ_TESTING)
diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt
new file mode 100644
index 000000000..05b4dd80a
--- /dev/null
+++ b/tests/fuzz/CMakeLists.txt
@@ -0,0 +1,54 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+add_definitions(${C_STANDARD_FLAGS} ${COMPILE_WARNING_FLAGS})
+
+option(FUZZ_REGRESSION_TESTS "Run fuzz tests with regression test driver" ON)
+option(FUZZ_LONG_TESTS "Run fuzz tests that take a long time" OFF)
+set(FUZZER AFL CACHE STRING "Fuzzing engine to use") # Set AFL as the default fuzzer
+set(FUZZING_LIB_LibFuzzer FuzzingEngine)
+set(FUZZING_LIB_AFL -fsanitize=fuzzer)
+
+add_library(StandaloneFuzzTargetMain STATIC StandaloneFuzzTargetMain.c StandaloneFuzzTargetInit.c)
+
+if (FUZZ_REGRESSION_TESTS)
+ message(STATUS "FUZZ_REGRESSION_TESTS")
+ set(FUZZING_LIBRARY StandaloneFuzzTargetMain)
+else ()
+ message(STATUS "NO FUZZ_REGRESSION_TESTS")
+ set(FUZZING_LIBRARY ${FUZZING_LIB_${FUZZER}})
+endif ()
+
+macro(add_fuzz_test test)
+ add_executable (${test} ${ARGN})
+ target_link_libraries (${test} ${FUZZING_LIBRARY} skupper-router)
+ set_target_properties(fuzz_http2_decoder PROPERTIES LINKER_LANGUAGE CXX)
+
+ if(FUZZ_REGRESSION_TESTS)
+ file(GLOB_RECURSE files ${CMAKE_CURRENT_SOURCE_DIR}/${test}/*)
+ unset(file_lines)
+ foreach(f IN LISTS files)
+ set(file_lines "${file_lines}${f}\n")
+ endforeach()
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${test}-files" "${file_lines}")
+ add_test(${test} ${TEST_WRAP} ${test} "@${CMAKE_CURRENT_BINARY_DIR}/${test}-files")
+ endif(FUZZ_REGRESSION_TESTS)
+endmacro(add_fuzz_test test)
+
+add_fuzz_test(fuzz_http2_decoder fuzz_http2_decoder.c)
+#add_fuzz_test(fuzz_http1_decoder fuzz_http1_decoder.c)
diff --git a/tests/fuzz/Containerfile b/tests/fuzz/Containerfile
new file mode 100644
index 000000000..0205d7ea5
--- /dev/null
+++ b/tests/fuzz/Containerfile
@@ -0,0 +1,60 @@
+# Copyright 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+RUN apt-get update
+# Ensure we work from right python version
+# Minimum python version required by qpid-proton and skupper-router is Python 3.9
+RUN apt-get install -y python3.9 python3.9-dev && \
+ ln --force -s /usr/bin/python3.9 /usr/local/bin/python3 && \
+ apt-get install -y python3-pip
+RUN apt-get install -y libuv1-dev wget cmake emacs python3-dev libwebsockets-dev libtool zlib1g-dev cmake libsasl2-dev libssl-dev sasl2-bin libnghttp2-dev
+
+# LibwebSockets library is required by skupper-router
+# We are using v4.2-stable instead v4.3-stable because of this lws compilation error - https://github.com/warmcat/libwebsockets/issues/3163
+RUN git clone https://github.com/warmcat/libwebsockets.git --branch v4.2-stable
+WORKDIR /src
+RUN mkdir libwebsockets/build && cd libwebsockets/build && cmake .. -DLWS_LINK_TESTAPPS_DYNAMIC=ON -DLWS_WITH_LIBUV=OFF -DLWS_WITHOUT_BUILTIN_GETIFADDRS=ON -DLWS_WITHOUT_BUILTIN_SHA1=ON -DLWS_WITH_STATIC=OFF -DLWS_IPV6=ON -DLWS_WITH_HTTP2=OFF -DLWS_WITHOUT_CLIENT=OFF -DLWS_WITHOUT_SERVER=OFF -DLWS_WITHOUT_TESTAPPS=ON -DLWS_WITHOUT_TEST_SERVER=ON -DLWS_WITHOUT_TEST_SERVER_EXTPOLL=ON -DLWS_WITHOUT_TEST_PING=ON -DLWS_WITHOUT_TEST_CLIENT=ON && make install
+
+RUN git clone https://github.com/apache/qpid-proton.git
+WORKDIR /src/qpid-proton
+RUN mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF -DENABLE_LINKTIME_OPTIMIZATION=OFF -DBUILD_TLS=ON -DSSL_IMPL=openssl -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF && make install
+
+WORKDIR /src
+RUN git clone https://github.com/skupperproject/skupper-router.git
+
+WORKDIR /src/skupper-router
+
+# refresh the build directory if it exists already
+RUN rm build -rf || true
+
+# /usr/local/bin/compile compiles libFuzzer or AmericanFuzzyLop(afl), then calls /src/build.sh and sets correct environment variables for it
+RUN echo cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF -DFUZZ_REGRESSION_TESTS=OFF -DCMAKE_C_FLAGS=-DQD_MEMORY_DEBUG -DRUNTIME_CHECK=asan > /src/build.sh
+
+# build and run the test. Choose AFL for fuzzer
+RUN mkdir build
+WORKDIR /src/skupper-router/build
+RUN FUZZING_LANGUAGE='' FUZZING_ENGINE=afl /usr/local/bin/compile
+WORKDIR /src/skupper-router/build/tests/fuzz
+RUN make
+
+# Run one of the following commands to run the http1 or http2 fuzzer.
+# Starts the AFL fuzzer that runs in an infinite loop. Let it run for about 30 minutes and press Ctrl + C to kill it.
+# The AFL program displays the stats on stdout upon termination.
+#LD_LIBRARY_PATH=/usr/local/lib/clang/18/lib/x86_64-unknown-linux-gnu/ AFL_MAP_SIZE=10000000 AFL_DEBUG=1 AFL_SKIP_CPUFREQ=1 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 afl-fuzz -i /src/skupper-router/tests/fuzz/fuzz_http1_decoder/corpus/ -o findings_dir /src/skupper-router/build/tests/fuzz/fuzz_http1_decoder; fi
+#LD_LIBRARY_PATH=/usr/local/lib/clang/18/lib/x86_64-unknown-linux-gnu/ AFL_MAP_SIZE=10000000 AFL_DEBUG=1 AFL_SKIP_CPUFREQ=1 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 afl-fuzz -i /src/skupper-router/tests/fuzz/fuzz_http2_decoder/corpus/ -o findings_dir /src/skupper-router/build/tests/fuzz/fuzz_http2_decoder; fi
+CMD ["/bin/bash"]
+
diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md
new file mode 100644
index 000000000..e8e9ffd17
--- /dev/null
+++ b/tests/fuzz/README.md
@@ -0,0 +1,43 @@
+# Fuzz testing http1 and http2 adaptors in skupper-router
+
+## Basics
+
+For a glossary of fuzzing terms please see - https://github.com/google/fuzzing/blob/master/docs/glossary.md
+libFuzzer(https://llvm.org/docs/LibFuzzer.html) and AFL(https://github.com/google/AFL) are popular fuzzing engines that can be used for fuzz testing the http1 and the http2 adaptors.
+OSS-Fuzz (https://github.com/google/oss-fuzz) supports both libFuzzer and AFL.
+
+## skupper-router/tests/fuzz/CMakeLists.txt
+The CMakeLists.txt by defaults the fuzzing engine to AFL.
+```
+set(FUZZER AFL CACHE STRING "Fuzzing engine to use")
+```
+You can change the default fuzzing engine to libFuzzer like this -
+```
+set(FUZZER LibFuzzer CACHE STRING "Fuzzing engine to use")
+```
+The StandaloneFuzzTargetMain is set as the FUZZING_LIBRARY when regression testing is required (FUZZ_REGRESSION_TESTS=ON)
+The regression tests are run as part of the skupper-router test suite in github CI.
+The corpus files used by the regression tests are generated by running the fuzzer of your choice inside the container built using the Containerfile which is found in the skupper-router/tests/fuzz folder.
+
+## Containerfile
+
+skupper-router/tests/fuzzContainerfile creates an environment where you can run the fuzzer of your choice. You will need to have seed corpus files which the fuzzer will use and build upon to create numerous additional corpus files.
+If the code crashes, the input that led to the crash is saved. The crash files and the corpus files are downloaded from the container and used in regression testing.
+
+## Building and running Containerfile
+To build the Containerfile from the skupper-router/tests/fuzz/folder
+```
+ podman build -t oss-fuzz/skupper-router --file=Containerfile .
+```
+To run the container
+```
+ podman run --net host -i -t oss-fuzz/skupper-router
+```
+
+Notice in the Containerfile the two commented ENTRYPOINT lines.
+Once you are inside the container, run the AFL fuzzer as seen in the commented ENTRYPOINT lines. For example, to run the http2 fuzzing -
+```
+LD_LIBRARY_PATH=/usr/local/lib/clang/18/lib/x86_64-unknown-linux-gnu/ AFL_MAP_SIZE=10000000 AFL_DEBUG=1 AFL_SKIP_CPUFREQ=1 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 afl-fuzz -i /src/skupper-router/tests/fuzz/fuzz_http2_decoder/corpus/ -o findings_dir /src/skupper-router/build/tests/fuzz/fuzz_http2_decoder
+```
+Let the fuzzer run for about an hour. Since the fuzzer runs infinitely, to stop the fuzzer, press Ctrl + C. Check for the findings_dir for crashes and additional corpus files. Download the crash and corpus files from the container and run them locally against your code to help fix the crashes.
+
diff --git a/tests/fuzz/StandaloneFuzzTargetInit.c b/tests/fuzz/StandaloneFuzzTargetInit.c
new file mode 100644
index 000000000..69c110494
--- /dev/null
+++ b/tests/fuzz/StandaloneFuzzTargetInit.c
@@ -0,0 +1,28 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "libFuzzingEngine.h"
+
+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+ return 0;
+}
+
diff --git a/tests/fuzz/StandaloneFuzzTargetMain.c b/tests/fuzz/StandaloneFuzzTargetMain.c
new file mode 100644
index 000000000..3a372cf77
--- /dev/null
+++ b/tests/fuzz/StandaloneFuzzTargetMain.c
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*===- StandaloneFuzzTargetMain.c - standalone main() for fuzz targets. ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This main() function can be linked to a fuzz target (i.e. a library
+// that exports LLVMFuzzerTestOneInput() and possibly LLVMFuzzerInitialize())
+// instead of libFuzzer. This main() function will not perform any fuzzing
+// but will simply feed all input files one by one to the fuzz target.
+//
+// Use this file to provide reproducers for bugs when linking against libFuzzer
+// or other fuzzing engine is undesirable.
+//===----------------------------------------------------------------------===*/
+#include
+#include
+#include
+#include
+
+#include "libFuzzingEngine.h"
+
+/*
+ * Use this to implement response file:
+ * - Check if there is one file mentioned and its name starts with '@'
+ * - If so then read the file line by line making up the new argv
+ * - Modify argc/argv then return.
+ *
+ */
+
+/* Free allocated memory at program exit to avoid the leak sanitizer complaining */
+static char *buf = 0;
+static char **nargv = 0;
+
+static void freeall(void)
+{
+ free(buf);
+ free(nargv);
+}
+
+int ProcessResponseFile(int *argc, char ***argv) {
+ if (*argc==2 && (*argv)[1][0]=='@') {
+ const char* rfilename = (*argv)[1]+1;
+
+ /* Read entire file into memory */
+ fprintf(stderr, "Reading response file: %s\n", rfilename);
+ FILE *f = fopen(rfilename, "rb");
+ assert(f);
+ fseek(f, 0, SEEK_END);
+ size_t len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ buf = (char*)malloc(len+1);
+ size_t n_read = fread(buf, 1, len, f);
+ fclose(f);
+ assert(n_read == len);
+ buf[len] = '\0';
+
+ /* scan file counting lines and replacing line ends with \0 */
+ int line = 0;
+ char *p = buf;
+ while (p<&buf[len]) {
+ p += strcspn(p, "\n\r ");
+ *p++ = '\0';
+ line +=1;
+ };
+
+ fprintf(stderr, " response file: (%zd bytes, %d lines)\n", n_read, line);
+
+ /* scan again putting each line into the argv array */
+ nargv = (char**) calloc(line+1, sizeof(p));
+
+ p = buf;
+ line = 1;
+ do {
+ char* s = p;
+ int l = strlen(p);
+ p += l+1;
+ if (l>0) nargv[line++] = s;
+ } while (p<&buf[len]);
+
+ int nargc = line;
+ *argc = nargc;
+ *argv = nargv;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
+ LLVMFuzzerInitialize(&argc, &argv);
+
+ // Process response file
+ ProcessResponseFile(&argc, &argv);
+
+ for (int i = 1; i < argc; i++) {
+ fprintf(stderr, "Running: %s\n", argv[i]);
+ FILE *f = fopen(argv[i], "rb");
+ assert(f);
+ fseek(f, 0, SEEK_END);
+ size_t len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ unsigned char *buf = (unsigned char*)malloc(len);
+ size_t n_read = fread(buf, 1, len, f);
+ fclose(f);
+ assert(n_read == len);
+ LLVMFuzzerTestOneInput(buf, len);
+ free(buf);
+ fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
+ }
+ freeall();
+}
diff --git a/tests/fuzz/fuzz_http2_decoder.c b/tests/fuzz/fuzz_http2_decoder.c
new file mode 100644
index 000000000..c07717d8b
--- /dev/null
+++ b/tests/fuzz/fuzz_http2_decoder.c
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include
+
+#include "decoders/http2/http2_decoder.h"
+#include "decoders/http2/http2_test.h"
+#include "qpid/dispatch/ctools.h"
+
+#include "libFuzzingEngine.h"
+
+void qd_log_initialize(void);
+void qd_error_initialize(void);
+void qd_router_id_finalize(void);
+void qd_log_finalize(void);
+
+/**
+ * This function is processed on exit
+ */
+void call_on_exit(void)
+{
+ qd_log_finalize();
+ qd_alloc_finalize();
+ qd_router_id_finalize();
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+ atexit(call_on_exit);
+
+ qd_alloc_initialize();
+ qd_log_initialize();
+ qd_error_initialize();
+ return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ qd_http2_decoder_connection_t *conn_state = qd_http2_decoder_connection(0, 0/*user_context*/, 1/*conn_id*/);
+ decode(conn_state, true, data, size);
+ qd_http2_decoder_connection_free(conn_state);
+ //qd_http2_decoder_connection_final();
+ return 0;
+}
+
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000000,time:0,execs:0,orig:file b/tests/fuzz/fuzz_http2_decoder/corpus/id:000000,time:0,execs:0,orig:file
new file mode 100644
index 000000000..0d3b835ad
--- /dev/null
+++ b/tests/fuzz/fuzz_http2_decoder/corpus/id:000000,time:0,execs:0,orig:file
@@ -0,0 +1,4 @@
+PRI * HTTP/2.0
+
+SM
+
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000001,time:0,execs:0,orig:file2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000001,time:0,execs:0,orig:file2
new file mode 100644
index 000000000..362b8cac8
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000001,time:0,execs:0,orig:file2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000002,src:000001,time:9,execs:57,op:havoc,rep:14,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000002,src:000001,time:9,execs:57,op:havoc,rep:14,+cov
new file mode 100644
index 000000000..0c535bee8
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000002,src:000001,time:9,execs:57,op:havoc,rep:14,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000003,src:000001,time:11,execs:66,op:havoc,rep:12,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000003,src:000001,time:11,execs:66,op:havoc,rep:12,+cov
new file mode 100644
index 000000000..05484bfbb
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000003,src:000001,time:11,execs:66,op:havoc,rep:12,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000004,src:000001,time:16,execs:98,op:havoc,rep:3,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000004,src:000001,time:16,execs:98,op:havoc,rep:3,+cov
new file mode 100644
index 000000000..74ceb214f
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000004,src:000001,time:16,execs:98,op:havoc,rep:3,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000005,src:000001,time:18,execs:111,op:havoc,rep:1,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000005,src:000001,time:18,execs:111,op:havoc,rep:1,+cov
new file mode 100644
index 000000000..758806860
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000005,src:000001,time:18,execs:111,op:havoc,rep:1,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000006,src:000001,time:20,execs:124,op:havoc,rep:3 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000006,src:000001,time:20,execs:124,op:havoc,rep:3
new file mode 100644
index 000000000..608bbadd7
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000006,src:000001,time:20,execs:124,op:havoc,rep:3 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000007,src:000001,time:22,execs:144,op:havoc,rep:16 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000007,src:000001,time:22,execs:144,op:havoc,rep:16
new file mode 100644
index 000000000..1818e4e5c
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000007,src:000001,time:22,execs:144,op:havoc,rep:16 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000008,src:000001,time:25,execs:181,op:havoc,rep:1 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000008,src:000001,time:25,execs:181,op:havoc,rep:1
new file mode 100644
index 000000000..61ca6a05f
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000008,src:000001,time:25,execs:181,op:havoc,rep:1 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000009,src:000001,time:26,execs:194,op:havoc,rep:2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000009,src:000001,time:26,execs:194,op:havoc,rep:2
new file mode 100644
index 000000000..7745db4df
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000009,src:000001,time:26,execs:194,op:havoc,rep:2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000010,src:000001,time:29,execs:223,op:havoc,rep:5 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000010,src:000001,time:29,execs:223,op:havoc,rep:5
new file mode 100644
index 000000000..8a0483a1a
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000010,src:000001,time:29,execs:223,op:havoc,rep:5 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000011,src:000001,time:32,execs:275,op:havoc,rep:3,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000011,src:000001,time:32,execs:275,op:havoc,rep:3,+cov
new file mode 100644
index 000000000..d6b5704a8
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000011,src:000001,time:32,execs:275,op:havoc,rep:3,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000012,src:000001,time:41,execs:413,op:havoc,rep:3 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000012,src:000001,time:41,execs:413,op:havoc,rep:3
new file mode 100644
index 000000000..0130e3910
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000012,src:000001,time:41,execs:413,op:havoc,rep:3 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000013,src:000001,time:46,execs:504,op:havoc,rep:1,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000013,src:000001,time:46,execs:504,op:havoc,rep:1,+cov
new file mode 100644
index 000000000..8a1e17daf
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000013,src:000001,time:46,execs:504,op:havoc,rep:1,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000014,src:000001,time:54,execs:622,op:havoc,rep:5,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000014,src:000001,time:54,execs:622,op:havoc,rep:5,+cov
new file mode 100644
index 000000000..96b85b632
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000014,src:000001,time:54,execs:622,op:havoc,rep:5,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000015,src:000001,time:57,execs:667,op:havoc,rep:3,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000015,src:000001,time:57,execs:667,op:havoc,rep:3,+cov
new file mode 100644
index 000000000..48d7ba937
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000015,src:000001,time:57,execs:667,op:havoc,rep:3,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000018,src:000001,time:97,execs:1350,op:havoc,rep:8 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000018,src:000001,time:97,execs:1350,op:havoc,rep:8
new file mode 100644
index 000000000..32c030b9d
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000018,src:000001,time:97,execs:1350,op:havoc,rep:8 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000019,src:000001,time:114,execs:1633,op:havoc,rep:6 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000019,src:000001,time:114,execs:1633,op:havoc,rep:6
new file mode 100644
index 000000000..0a2ec16f5
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000019,src:000001,time:114,execs:1633,op:havoc,rep:6 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000020,src:000001,time:135,execs:1942,op:havoc,rep:16,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000020,src:000001,time:135,execs:1942,op:havoc,rep:16,+cov
new file mode 100644
index 000000000..a44d70de4
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000020,src:000001,time:135,execs:1942,op:havoc,rep:16,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000021,src:000001,time:297,execs:4435,op:havoc,rep:1 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000021,src:000001,time:297,execs:4435,op:havoc,rep:1
new file mode 100644
index 000000000..b04465a0d
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000021,src:000001,time:297,execs:4435,op:havoc,rep:1 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000023,src:000016+000015,time:844,execs:14581,op:splice,rep:1 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000023,src:000016+000015,time:844,execs:14581,op:splice,rep:1
new file mode 100644
index 000000000..5bd1a2a7d
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000023,src:000016+000015,time:844,execs:14581,op:splice,rep:1 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000024,src:000020,time:1595,execs:29722,op:havoc,rep:2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000024,src:000020,time:1595,execs:29722,op:havoc,rep:2
new file mode 100644
index 000000000..d6f1967c1
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000024,src:000020,time:1595,execs:29722,op:havoc,rep:2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000025,src:000014,time:2149,execs:39258,op:havoc,rep:7 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000025,src:000014,time:2149,execs:39258,op:havoc,rep:7
new file mode 100644
index 000000000..3147fd7ef
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000025,src:000014,time:2149,execs:39258,op:havoc,rep:7 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000026,src:000014,time:2154,execs:39348,op:havoc,rep:6 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000026,src:000014,time:2154,execs:39348,op:havoc,rep:6
new file mode 100644
index 000000000..03a4253cb
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000026,src:000014,time:2154,execs:39348,op:havoc,rep:6 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000027,src:000025,time:2588,execs:46911,op:havoc,rep:2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000027,src:000025,time:2588,execs:46911,op:havoc,rep:2
new file mode 100644
index 000000000..81a28d07f
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000027,src:000025,time:2588,execs:46911,op:havoc,rep:2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000028,src:000016+000008,time:3033,execs:55613,op:splice,rep:2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000028,src:000016+000008,time:3033,execs:55613,op:splice,rep:2
new file mode 100644
index 000000000..55200d715
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000028,src:000016+000008,time:3033,execs:55613,op:splice,rep:2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000029,src:000016+000018,time:16456,execs:313183,op:splice,rep:5 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000029,src:000016+000018,time:16456,execs:313183,op:splice,rep:5
new file mode 100644
index 000000000..d2d3a6fa6
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000029,src:000016+000018,time:16456,execs:313183,op:splice,rep:5 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000031,src:000021+000005,time:52315,execs:985143,op:splice,rep:10,+cov b/tests/fuzz/fuzz_http2_decoder/corpus/id:000031,src:000021+000005,time:52315,execs:985143,op:splice,rep:10,+cov
new file mode 100644
index 000000000..8c0113ccc
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000031,src:000021+000005,time:52315,execs:985143,op:splice,rep:10,+cov differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000032,src:000021+000026,time:63268,execs:1174313,op:splice,rep:13 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000032,src:000021+000026,time:63268,execs:1174313,op:splice,rep:13
new file mode 100644
index 000000000..f4e537ce3
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000032,src:000021+000026,time:63268,execs:1174313,op:splice,rep:13 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000034,src:000014,time:209083,execs:3978023,op:havoc,rep:3 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000034,src:000014,time:209083,execs:3978023,op:havoc,rep:3
new file mode 100644
index 000000000..af87ef828
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000034,src:000014,time:209083,execs:3978023,op:havoc,rep:3 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000036,src:000035,time:386748,execs:6805442,op:havoc,rep:1 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000036,src:000035,time:386748,execs:6805442,op:havoc,rep:1
new file mode 100644
index 000000000..bb243faec
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000036,src:000035,time:386748,execs:6805442,op:havoc,rep:1 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000037,src:000036,time:389018,execs:6830806,op:havoc,rep:2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000037,src:000036,time:389018,execs:6830806,op:havoc,rep:2
new file mode 100644
index 000000000..7516ba170
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000037,src:000036,time:389018,execs:6830806,op:havoc,rep:2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000038,src:000037,time:395813,execs:6924470,op:havoc,rep:1 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000038,src:000037,time:395813,execs:6924470,op:havoc,rep:1
new file mode 100644
index 000000000..1c1ab9197
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000038,src:000037,time:395813,execs:6924470,op:havoc,rep:1 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000039,src:000037,time:395822,execs:6924599,op:havoc,rep:2 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000039,src:000037,time:395822,execs:6924599,op:havoc,rep:2
new file mode 100644
index 000000000..c9dd8af7f
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000039,src:000037,time:395822,execs:6924599,op:havoc,rep:2 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000040,src:000039,time:409617,execs:7109000,op:havoc,rep:3 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000040,src:000039,time:409617,execs:7109000,op:havoc,rep:3
new file mode 100644
index 000000000..cfe7cfa6f
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000040,src:000039,time:409617,execs:7109000,op:havoc,rep:3 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000041,src:000034+000029,time:600293,execs:9927577,op:splice,rep:3 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000041,src:000034+000029,time:600293,execs:9927577,op:splice,rep:3
new file mode 100644
index 000000000..cd7274680
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000041,src:000034+000029,time:600293,execs:9927577,op:splice,rep:3 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000042,src:000034+000022,time:600658,execs:9930663,op:splice,rep:3 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000042,src:000034+000022,time:600658,execs:9930663,op:splice,rep:3
new file mode 100644
index 000000000..2280a0418
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000042,src:000034+000022,time:600658,execs:9930663,op:splice,rep:3 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/id:000043,src:000036,time:600813,execs:9933283,op:havoc,rep:20 b/tests/fuzz/fuzz_http2_decoder/corpus/id:000043,src:000036,time:600813,execs:9933283,op:havoc,rep:20
new file mode 100644
index 000000000..e7437f855
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/id:000043,src:000036,time:600813,execs:9933283,op:havoc,rep:20 differ
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/original-seed1 b/tests/fuzz/fuzz_http2_decoder/corpus/original-seed1
new file mode 100644
index 000000000..0d3b835ad
--- /dev/null
+++ b/tests/fuzz/fuzz_http2_decoder/corpus/original-seed1
@@ -0,0 +1,4 @@
+PRI * HTTP/2.0
+
+SM
+
diff --git a/tests/fuzz/fuzz_http2_decoder/corpus/original-seed2 b/tests/fuzz/fuzz_http2_decoder/corpus/original-seed2
new file mode 100644
index 000000000..2ccb96c53
Binary files /dev/null and b/tests/fuzz/fuzz_http2_decoder/corpus/original-seed2 differ
diff --git a/tests/fuzz/libFuzzingEngine.h b/tests/fuzz/libFuzzingEngine.h
new file mode 100644
index 000000000..c2877d180
--- /dev/null
+++ b/tests/fuzz/libFuzzingEngine.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#ifndef _LIB_FUZZING_ENGINE_H_
+#define _LIB_FUZZING_ENGINE_H_
+
+#include
+#include
+
+// This header defines `extern "C"` for the fuzzing interface functions
+
+#ifdef __cplusplus
+extern "C"
+#endif
+int LLVMFuzzerInitialize(int *argc, char ***argv);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+
+#endif