From 3f9a1253d832de13605049a43bfd0779e326d1cb Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 17 Feb 2026 15:12:59 -0800 Subject: [PATCH 1/7] Add initial support for libfuzzer --- CMakeLists.txt | 14 +++ README.md | 13 +++ fuzzing/CMakeLists.txt | 6 ++ fuzzing/Dockerfile | 8 ++ .../fuzz_targets/j2c_expand_fuzz_target.cpp | 96 +++++++++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 fuzzing/CMakeLists.txt create mode 100644 fuzzing/Dockerfile create mode 100644 fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ec52e7c..710d78fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,3 +238,17 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND OJPH_BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() + +################################################################################################ +# Fuzzing +################################################################################################ + +option(ENABLE_FUZZING "Enable fuzzing" OFF) + +if(ENABLE_FUZZING) + if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(FATAL_ERROR "Fuzzing requires a Clang toolchain.") + endif() + + add_subdirectory(fuzzing) +endif() \ No newline at end of file diff --git a/README.md b/README.md index 90064a73..fa7f5092 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,16 @@ The standard is available free of charge from [ITU website](https://www.itu.int/ # Repositories # [![Packaging status](https://repology.org/badge/vertical-allrepos/openjph.svg)](https://repology.org/project/openjph/versions) +# Fuzzer Target # + +Fuzzer targets can be build using the `ENABLE_FUZZING` build option. The Dockerfile in the `fuzzing directory` allows local testing: + +```sh +podman build -t openjph-fuzz -f fuzzing/Dockerfile +podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash +image# mkdir /app/build/ +image# cd /app/build/ +image# cmake /app/ojph -DENABLE_FUZZING=ON +image# make +image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c +``` diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt new file mode 100644 index 00000000..48cc78fd --- /dev/null +++ b/fuzzing/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(j2c_expand_fuzz_target fuzz_targets/j2c_expand_fuzz_target.cpp) + +target_compile_options(j2c_expand_fuzz_target PRIVATE -fsanitize=fuzzer,address) +target_link_options(j2c_expand_fuzz_target PRIVATE -fsanitize=fuzzer,address) +target_link_libraries(j2c_expand_fuzz_target PRIVATE openjph) + diff --git a/fuzzing/Dockerfile b/fuzzing/Dockerfile new file mode 100644 index 00000000..deb381b0 --- /dev/null +++ b/fuzzing/Dockerfile @@ -0,0 +1,8 @@ +FROM gcr.io/oss-fuzz-base/base-builder + +RUN apt-get update +RUN apt-get -y install cmake +RUN apt-get -y install libtiff-dev + +WORKDIR /app +RUN git clone --depth 1 https://github.com/aous72/jp2k_test_codestreams.git diff --git a/fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp b/fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp new file mode 100644 index 00000000..5b29225d --- /dev/null +++ b/fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp @@ -0,0 +1,96 @@ +//***************************************************************************/ +// This software is released under the 2-Clause BSD license, included +// below. +// +// Copyright (c) 2019, Aous Naman +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//***************************************************************************/ +// This file is part of the OpenJPH software implementation. +// File: j2c_expand_fuzz_target.cpp +// Author: Pierre-Anthony Lemieux +// Date: 17 February 2026 +//***************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + try + { + + ojph::mem_infile infile; + infile.open(reinterpret_cast(Data), Size); + + ojph::codestream cs; + cs.read_headers(&infile); + + cs.create(); + + if (cs.is_planar()) + { + ojph::param_siz siz = cs.access_siz(); + for (ojph::ui32 c = 0; c < siz.get_num_components(); ++c) + { + ojph::ui32 height = siz.get_recon_height(c); + for (ojph::ui32 i = height; i > 0; --i) + { + ojph::ui32 comp_num; + cs.pull(comp_num); + assert(comp_num == c); + } + } + } + else + { + ojph::param_siz siz = cs.access_siz(); + ojph::ui32 height = siz.get_recon_height(0); + for (ojph::ui32 i = 0; i < height; ++i) + { + for (ojph::ui32 c = 0; c < siz.get_num_components(); ++c) + { + ojph::ui32 comp_num; + cs.pull(comp_num); + assert(comp_num == c); + } + } + } + } + catch (const std::exception &e) + { + std::cerr << e.what() << '\n'; + } + return 0; +} From 386503c02135db7f9e3332428e9cfe41e329520e Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 17 Feb 2026 17:05:05 -0800 Subject: [PATCH 2/7] Add oss-fuzz detection and static build --- fuzzing/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index 48cc78fd..5b2e722b 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -1,6 +1,10 @@ -add_executable(j2c_expand_fuzz_target fuzz_targets/j2c_expand_fuzz_target.cpp) +if(DEFINED ENV{BUILD_UID}) + link_libraries($ENV{LIB_FUZZING_ENGINE}) +else() + add_compile_options(-fsanitize=fuzzer,address) + add_link_options(-fsanitize=fuzzer,address) +endif() -target_compile_options(j2c_expand_fuzz_target PRIVATE -fsanitize=fuzzer,address) -target_link_options(j2c_expand_fuzz_target PRIVATE -fsanitize=fuzzer,address) +add_executable(j2c_expand_fuzz_target fuzz_targets/j2c_expand_fuzz_target.cpp) target_link_libraries(j2c_expand_fuzz_target PRIVATE openjph) From 2ac825b7f009db65c4790868ee167bdd37843f56 Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 17 Feb 2026 17:07:08 -0800 Subject: [PATCH 3/7] Move README to fuzzing directory Rename ENABLE_FUZZING --- CMakeLists.txt | 4 ++-- README.md | 14 -------------- fuzzing/README.md | 13 +++++++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 fuzzing/README.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 710d78fc..7337734d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,9 +243,9 @@ endif() # Fuzzing ################################################################################################ -option(ENABLE_FUZZING "Enable fuzzing" OFF) +option(OJPH_ENABLE_FUZZING "Enable fuzzing" OFF) -if(ENABLE_FUZZING) +if(OJPH_ENABLE_FUZZING) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(FATAL_ERROR "Fuzzing requires a Clang toolchain.") endif() diff --git a/README.md b/README.md index fa7f5092..5ddf1914 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,3 @@ The standard is available free of charge from [ITU website](https://www.itu.int/ # Repositories # [![Packaging status](https://repology.org/badge/vertical-allrepos/openjph.svg)](https://repology.org/project/openjph/versions) - -# Fuzzer Target # - -Fuzzer targets can be build using the `ENABLE_FUZZING` build option. The Dockerfile in the `fuzzing directory` allows local testing: - -```sh -podman build -t openjph-fuzz -f fuzzing/Dockerfile -podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash -image# mkdir /app/build/ -image# cd /app/build/ -image# cmake /app/ojph -DENABLE_FUZZING=ON -image# make -image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c -``` diff --git a/fuzzing/README.md b/fuzzing/README.md new file mode 100644 index 00000000..602b548d --- /dev/null +++ b/fuzzing/README.md @@ -0,0 +1,13 @@ +# Fuzzer Target # + +Fuzzer targets can be build using the `ENABLE_FUZZING` build option. The Dockerfile in the `fuzzing directory` allows local testing: + +```sh +podman build -t openjph-fuzz -f fuzzing/Dockerfile +podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash +image# mkdir /app/build/ +image# cd /app/build/ +image# cmake /app/ojph -DOJPH_ENABLE_FUZZING=ON -DBUILD_SHARED_LIBS=OFF +image# make +image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c +``` \ No newline at end of file From f01797c731e16f2826f0dd9d95ec2e5805332088 Mon Sep 17 00:00:00 2001 From: Aous Naman Date: Wed, 18 Feb 2026 01:26:29 +0000 Subject: [PATCH 4/7] Renaming and moving things around. --- CMakeLists.txt | 5 ++--- README.md | 1 + docs/fuzzing.md | 13 +++++++++++++ fuzzing/CMakeLists.txt | 4 ++-- fuzzing/README.md | 13 ------------- ..._fuzz_target.cpp => ojph_expand_fuzz_target.cpp} | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) create mode 100644 docs/fuzzing.md delete mode 100644 fuzzing/README.md rename fuzzing/fuzz_targets/{j2c_expand_fuzz_target.cpp => ojph_expand_fuzz_target.cpp} (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7337734d..689e926d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ option(OJPH_ENABLE_TIFF_SUPPORT "Enables input and output support for TIFF files option(OJPH_BUILD_TESTS "Enables building test code" OFF) option(OJPH_BUILD_EXECUTABLES "Enables building command line executables" ON) option(OJPH_BUILD_STREAM_EXPAND "Enables building ojph_stream_expand executable" OFF) +option(OJPH_BUILD_FUZZER "Enables building oss-fuzzing target executable" OFF) option(OJPH_DISABLE_SIMD "Disables the use of SIMD instructions -- agnostic to architectures" OFF) option(OJPH_DISABLE_SSE "Disables the use of SSE SIMD instructions and associated files" OFF) @@ -243,9 +244,7 @@ endif() # Fuzzing ################################################################################################ -option(OJPH_ENABLE_FUZZING "Enable fuzzing" OFF) - -if(OJPH_ENABLE_FUZZING) +if(OJPH_BUILD_FUZZER) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(FATAL_ERROR "Fuzzing requires a Clang toolchain.") endif() diff --git a/README.md b/README.md index 5ddf1914..19811cac 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ The standard is available free of charge from [ITU website](https://www.itu.int/ * [Usage Example](./docs/usage_examples.md) * [Web-based Demos](./docs/web_demos.md) * [Doxygen Documentation Style](./docs/doxygen_style.md) +* [OSS-Fuzzing](./docs/fuzzing.md) # Repositories # [![Packaging status](https://repology.org/badge/vertical-allrepos/openjph.svg)](https://repology.org/project/openjph/versions) diff --git a/docs/fuzzing.md b/docs/fuzzing.md new file mode 100644 index 00000000..ca599ceb --- /dev/null +++ b/docs/fuzzing.md @@ -0,0 +1,13 @@ +# Fuzzer Target # + +Fuzzer targets can be build using the `OJPH_BUILD_FUZZER` build option. The Dockerfile in the `fuzzing directory` allows local testing: + +```sh +podman build -t openjph-fuzz -f fuzzing/Dockerfile +podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash +image# mkdir /app/build/ +image# cd /app/build/ +image# cmake /app/ojph -DOJPH_BUILD_FUZZER=ON -DBUILD_SHARED_LIBS=OFF +image# make +image# ./fuzzing/ojph_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c +``` diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index 5b2e722b..e099cf52 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -5,6 +5,6 @@ else() add_link_options(-fsanitize=fuzzer,address) endif() -add_executable(j2c_expand_fuzz_target fuzz_targets/j2c_expand_fuzz_target.cpp) -target_link_libraries(j2c_expand_fuzz_target PRIVATE openjph) +add_executable(ojph_expand_fuzz_target fuzz_targets/ojph_expand_fuzz_target.cpp) +target_link_libraries(ojph_expand_fuzz_target PRIVATE openjph) diff --git a/fuzzing/README.md b/fuzzing/README.md deleted file mode 100644 index 602b548d..00000000 --- a/fuzzing/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Fuzzer Target # - -Fuzzer targets can be build using the `ENABLE_FUZZING` build option. The Dockerfile in the `fuzzing directory` allows local testing: - -```sh -podman build -t openjph-fuzz -f fuzzing/Dockerfile -podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash -image# mkdir /app/build/ -image# cd /app/build/ -image# cmake /app/ojph -DOJPH_ENABLE_FUZZING=ON -DBUILD_SHARED_LIBS=OFF -image# make -image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c -``` \ No newline at end of file diff --git a/fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp b/fuzzing/fuzz_targets/ojph_expand_fuzz_target.cpp similarity index 98% rename from fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp rename to fuzzing/fuzz_targets/ojph_expand_fuzz_target.cpp index 5b29225d..8c8be78b 100644 --- a/fuzzing/fuzz_targets/j2c_expand_fuzz_target.cpp +++ b/fuzzing/fuzz_targets/ojph_expand_fuzz_target.cpp @@ -28,7 +28,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //***************************************************************************/ // This file is part of the OpenJPH software implementation. -// File: j2c_expand_fuzz_target.cpp +// File: ojph_expand_fuzz_target.cpp // Author: Pierre-Anthony Lemieux // Date: 17 February 2026 //***************************************************************************/ From cc81420ab8730d4ecff4e2d87e3fab41e5a3f5a7 Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 17 Feb 2026 18:46:37 -0800 Subject: [PATCH 5/7] Fix README --- fuzzing/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 fuzzing/README.md diff --git a/fuzzing/README.md b/fuzzing/README.md new file mode 100644 index 00000000..8d5e37b3 --- /dev/null +++ b/fuzzing/README.md @@ -0,0 +1,13 @@ +# Fuzzer Target # + +Fuzzer targets can be build using the `ENABLE_FUZZING` build option. The Dockerfile in the `fuzzing directory` allows local testing: + +```sh +podman build -t openjph-fuzz -f fuzzing/Dockerfile +podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash +image# mkdir /app/build/ +image# cd /app/build/ +image# cmake /app/ojph -DOJPH_ENABLE_FUZZING=ON -DBUILD_SHARED_LIBS=OFF +image# make +image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c +``` From 5ba6b7770a085081592f07a9490ec34f834b7cc3 Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 17 Feb 2026 18:47:34 -0800 Subject: [PATCH 6/7] Fix README --- fuzzing/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzzing/README.md b/fuzzing/README.md index 8d5e37b3..cdc3f1a5 100644 --- a/fuzzing/README.md +++ b/fuzzing/README.md @@ -1,13 +1,13 @@ # Fuzzer Target # -Fuzzer targets can be build using the `ENABLE_FUZZING` build option. The Dockerfile in the `fuzzing directory` allows local testing: +Fuzzer targets can be build using the `OJPH_BUILD_FUZZER` build option. The Dockerfile allows local testing: ```sh podman build -t openjph-fuzz -f fuzzing/Dockerfile podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash image# mkdir /app/build/ image# cd /app/build/ -image# cmake /app/ojph -DOJPH_ENABLE_FUZZING=ON -DBUILD_SHARED_LIBS=OFF +image# cmake /app/ojph -DOJPH_BUILD_FUZZER=ON -DBUILD_SHARED_LIBS=OFF image# make image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c ``` From 36e351f4175b220ab74392ad04ea4d555baf740b Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 17 Feb 2026 18:48:42 -0800 Subject: [PATCH 7/7] Remove unused README --- fuzzing/README.md | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 fuzzing/README.md diff --git a/fuzzing/README.md b/fuzzing/README.md deleted file mode 100644 index cdc3f1a5..00000000 --- a/fuzzing/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Fuzzer Target # - -Fuzzer targets can be build using the `OJPH_BUILD_FUZZER` build option. The Dockerfile allows local testing: - -```sh -podman build -t openjph-fuzz -f fuzzing/Dockerfile -podman run -it --rm -v $(pwd):/app/ojph/ openjph-fuzz bash -image# mkdir /app/build/ -image# cd /app/build/ -image# cmake /app/ojph -DOJPH_BUILD_FUZZER=ON -DBUILD_SHARED_LIBS=OFF -image# make -image# ./fuzzing/j2c_expand_fuzz_target /app/jp2k_test_codestreams/openjph/*.j2c -```