diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile new file mode 100644 index 000000000..82fadacbb --- /dev/null +++ b/.clusterfuzzlite/Dockerfile @@ -0,0 +1,5 @@ +FROM gcr.io/oss-fuzz-base/base-builder-go +RUN git clone --depth 1 https://github.com/containrrr/shoutrrr +COPY . $SRC/shoutrrr +WORKDIR $SRC/shoutrrr +COPY ./clusterfuzzlite/build.sh $SRC/ diff --git a/.clusterfuzzlite/build.sh b/.clusterfuzzlite/build.sh new file mode 100644 index 000000000..d1f91ac82 --- /dev/null +++ b/.clusterfuzzlite/build.sh @@ -0,0 +1 @@ +compile_go_fuzzer github.com/containrrr/shoutrrr/pkg/util FuzzPartitionMessage fuzz_partition_message diff --git a/.clusterfuzzlite/project.yaml b/.clusterfuzzlite/project.yaml new file mode 100644 index 000000000..eb93f2786 --- /dev/null +++ b/.clusterfuzzlite/project.yaml @@ -0,0 +1 @@ +language: go \ No newline at end of file diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml new file mode 100644 index 000000000..080859c15 --- /dev/null +++ b/.github/workflows/cflite_pr.yml @@ -0,0 +1,29 @@ +name: ClusterFuzzLite PR fuzzing +on: + workflow_dispatch: + pull_request: + paths: + - '**' +permissions: read-all +jobs: + PR: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sanitizer: [address] + steps: + - name: Build Fuzzers (${{ matrix.sanitizer }}) + id: build + uses: google/clusterfuzzlite/actions/build_fuzzers@v1 + with: + sanitizer: ${{ matrix.sanitizer }} + language: go + - name: Run Fuzzers (${{ matrix.sanitizer }}) + id: run + uses: google/clusterfuzzlite/actions/run_fuzzers@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + fuzz-seconds: 400 + mode: 'code-change' + sanitizer: ${{ matrix.sanitizer }} diff --git a/pkg/util/fuzz.go b/pkg/util/fuzz.go new file mode 100644 index 000000000..6f071bbb5 --- /dev/null +++ b/pkg/util/fuzz.go @@ -0,0 +1,28 @@ +package util + +import ( + fuzz "github.com/AdaLogics/go-fuzz-headers" + t "github.com/containrrr/shoutrrr/pkg/types" +) + +func FuzzPartitionMessage(data []byte) int { + f := fuzz.NewConsumer(data) + + input, err := f.GetString() + if err != nil { + return 0 + } + + limits := t.MessageLimit{} + err = f.GenerateStruct(&limits) + if err != nil { + return 0 + } + + distance, err := f.GetInt() + if err != nil { + return 0 + } + _, _ = PartitionMessage(input, limits, distance) + return 1 +}