From c2978c4acfd2bfd42cb39a8c0846500b3cc7cef6 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 6 Sep 2022 22:55:51 +0100 Subject: [PATCH] fuzz: Refactor Fuzzers based on Go native fuzzing The existing fuzzers were converted into the Go native format. Based on how the code was structured on this project, the fuzzers can be quite effective, allowing for entire E2E fuzzing in some cases, but with very low execution cost. Signed-off-by: Paulo Gomes --- Makefile | 14 ++- go.mod | 2 + go.sum | 6 ++ internal/notifier/alertmanager_test.go | 39 +++++++ internal/notifier/azure_devops_test.go | 57 ++++++++++ internal/notifier/bitbucket_test.go | 55 ++++++++++ internal/notifier/discord_test.go | 39 +++++++ internal/notifier/forwarder_test.go | 33 ++++++ internal/notifier/github_test.go | 48 +++++++++ internal/notifier/gitlab_test.go | 47 ++++++++ internal/notifier/google_chat_test.go | 36 +++++++ internal/notifier/lark_test.go | 34 ++++++ internal/notifier/matrix_test.go | 38 +++++++ internal/notifier/opsgenie_test.go | 39 +++++++ internal/notifier/rocket_test.go | 40 +++++++ internal/notifier/slack_test.go | 41 +++++++ internal/notifier/teams_test.go | 41 +++++++ ...fcac2826e42cf062e44d8ced6561aa0b92dafedd65 | 8 ++ internal/notifier/util_test.go | 22 ++++ internal/notifier/webex_test.go | 40 +++++++ tests/fuzz/alertmanager_fuzzer.go | 55 ---------- tests/fuzz/azure_devops_fuzzer.go | 59 ---------- tests/fuzz/bitbucket_fuzzer.go | 59 ---------- tests/fuzz/discord_fuzzer.go | 64 ----------- tests/fuzz/forwarder_fuzzer.go | 56 ---------- tests/fuzz/github_fuzzer.go | 59 ---------- tests/fuzz/gitlab_fuzzer.go | 59 ---------- tests/fuzz/go.mod | 11 -- tests/fuzz/google_chat_fuzzer.go | 55 ---------- tests/fuzz/lark_fuzzer.go | 55 ---------- tests/fuzz/matrix_fuzzer.go | 59 ---------- tests/fuzz/native_go_run.sh | 36 +++++++ tests/fuzz/opsgenie_fuzzer.go | 55 ---------- tests/fuzz/oss_fuzz_build.sh | 101 ++++++++++-------- tests/fuzz/rocket_fuzzer.go | 64 ----------- tests/fuzz/slack_fuzzer.go | 69 ------------ tests/fuzz/teams_fuzzer.go | 55 ---------- tests/fuzz/util_fuzzer.go | 41 ------- tests/fuzz/webex_fuzzer.go | 55 ---------- 39 files changed, 770 insertions(+), 976 deletions(-) create mode 100644 internal/notifier/testdata/fuzz/FuzzDiscord/f00e373ef4651f2dc7c068fcac2826e42cf062e44d8ced6561aa0b92dafedd65 delete mode 100644 tests/fuzz/alertmanager_fuzzer.go delete mode 100644 tests/fuzz/azure_devops_fuzzer.go delete mode 100644 tests/fuzz/bitbucket_fuzzer.go delete mode 100644 tests/fuzz/discord_fuzzer.go delete mode 100644 tests/fuzz/forwarder_fuzzer.go delete mode 100644 tests/fuzz/github_fuzzer.go delete mode 100644 tests/fuzz/gitlab_fuzzer.go delete mode 100644 tests/fuzz/go.mod delete mode 100644 tests/fuzz/google_chat_fuzzer.go delete mode 100644 tests/fuzz/lark_fuzzer.go delete mode 100644 tests/fuzz/matrix_fuzzer.go create mode 100755 tests/fuzz/native_go_run.sh delete mode 100644 tests/fuzz/opsgenie_fuzzer.go delete mode 100644 tests/fuzz/rocket_fuzzer.go delete mode 100644 tests/fuzz/slack_fuzzer.go delete mode 100644 tests/fuzz/teams_fuzzer.go delete mode 100644 tests/fuzz/util_fuzzer.go delete mode 100644 tests/fuzz/webex_fuzzer.go diff --git a/Makefile b/Makefile index 5459fa1ba..fc31a4d96 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,10 @@ BUILD_PLATFORMS ?= linux/amd64 # Architecture to use envtest with ENVTEST_ARCH ?= amd64 +# FUZZ_TIME defines the max amount of time, in Go Duration, +# each fuzzer should run for. +FUZZ_TIME ?= 1m + all: manager # Run tests @@ -109,7 +113,7 @@ docker-push: docker-deploy: kubectl -n flux-system set image deployment/notification-controller manager=${IMG} -# Build fuzzers +# Build fuzzers used by oss-fuzz. fuzz-build: rm -rf $(shell pwd)/build/fuzz/ mkdir -p $(shell pwd)/build/fuzz/out/ @@ -122,7 +126,7 @@ fuzz-build: -v "$(shell pwd)/build/fuzz/out":/out \ local-fuzzing:latest -# Run each fuzzer once to ensure they are working +# Run each fuzzer once to ensure they will work when executed by oss-fuzz. fuzz-smoketest: fuzz-build docker run --rm \ -v "$(shell pwd)/build/fuzz/out":/out \ @@ -130,6 +134,12 @@ fuzz-smoketest: fuzz-build local-fuzzing:latest \ bash -c "/runner.sh" +# Run fuzz tests for the duration set in FUZZ_TIME. +fuzz-native: + KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \ + FUZZ_TIME=$(FUZZ_TIME) \ + ./tests/fuzz/native_go_run.sh + # Find or download controller-gen CONTROLLER_GEN = $(shell pwd)/bin/controller-gen .PHONY: controller-gen diff --git a/go.mod b/go.mod index fe794d15d..e4e9ce48b 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 replace github.com/fluxcd/notification-controller/api => ./api require ( + github.com/AdaLogics/go-fuzz-headers v0.0.0-20220903154154-e8044f6e4c72 github.com/Azure/azure-amqp-common-go/v3 v3.2.3 github.com/Azure/azure-event-hubs-go/v3 v3.3.18 github.com/containrrr/shoutrrr v0.6.1 @@ -68,6 +69,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect + github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/devigned/tab v0.1.1 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect diff --git a/go.sum b/go.sum index 701649898..eaf963c21 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20220903154154-e8044f6e4c72 h1:1sCHCT0xRr7UArrI1WJxsl9S8QeYdf0fmuGIl2xb7YI= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20220903154154-e8044f6e4c72/go.mod h1:i9fr2JpcEcY/IHEvzCM3qXUZYOQHgR89dt4es1CgMhc= github.com/Azure/azure-amqp-common-go/v3 v3.2.3 h1:uDF62mbd9bypXWi19V1bN5NZEO84JqgmI5G73ibAmrk= github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= github.com/Azure/azure-event-hubs-go/v3 v3.3.18 h1:jgWDk2qmknA0UsfyzjHiW5yciOw3aBY0Oq9p/M9lz2Q= @@ -169,6 +171,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -450,6 +454,7 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -1151,6 +1156,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= diff --git a/internal/notifier/alertmanager_test.go b/internal/notifier/alertmanager_test.go index 432ecd323..8cd45f445 100644 --- a/internal/notifier/alertmanager_test.go +++ b/internal/notifier/alertmanager_test.go @@ -24,7 +24,10 @@ import ( "net/http/httptest" "testing" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" + + fuzz "github.com/AdaLogics/go-fuzz-headers" ) func TestAlertmanager_Post(t *testing.T) { @@ -44,3 +47,39 @@ func TestAlertmanager_Post(t *testing.T) { err = alertmanager.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func Fuzz_AlertManager(f *testing.F) { + f.Add("update", "", []byte{}, []byte("{}")) + f.Add("something", "else", []byte{}, []byte("")) + + f.Fuzz(func(t *testing.T, + commitStatus, summary string, seed, response []byte) { + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(io.Discard, r.Body) + w.Write(response) + r.Body.Close() + })) + defer ts.Close() + + alertmanager, err := NewAlertmanager(ts.URL, "", nil) + if err != nil { + return + } + + event := events.Event{} + + // Try to fuzz the event object, but if it fails (not enough seed), + // ignore it, as other inputs are also being used in this test. + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil && (commitStatus != "" || summary != "") { + event.Metadata = map[string]string{ + "commit_status": commitStatus, + "summary": summary, + } + } + + _ = alertmanager.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/azure_devops_test.go b/internal/notifier/azure_devops_test.go index 75c49f0e3..f3d15deb8 100644 --- a/internal/notifier/azure_devops_test.go +++ b/internal/notifier/azure_devops_test.go @@ -17,10 +17,20 @@ limitations under the License. package notifier import ( + "context" + "crypto/x509" + "fmt" + "io" + "net/http" + "net/http/httptest" + "strings" "testing" + "github.com/fluxcd/pkg/runtime/events" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/git" "github.com/stretchr/testify/assert" + + fuzz "github.com/AdaLogics/go-fuzz-headers" ) func TestNewAzureDevOpsBasic(t *testing.T) { @@ -60,6 +70,53 @@ func TestDuplicateAzureDevOpsStatus(t *testing.T) { } } +const apiLocations = `{"count":0,"value":[{"area":"","id":"428dd4fb-fda5-4722-af02-9313b80305da","routeTemplate":"","resourceName":"","maxVersion":"6.0","minVersion":"5.0","releasedVersion":"6.0"}]}` + +func FuzzAzureDevOps(f *testing.F) { + f.Add("alakazam", "org/proj/_git/repo", "revision/dsa123a", "error", "", []byte{}, []byte(`{"count":1,"value":[{"state":"error","description":"","context":{"genre":"fluxcd","name":"/"}}]}`)) + f.Add("alakazam", "org/proj/_git/repo", "revision/dsa123a", "info", "", []byte{}, []byte(`{"count":1,"value":[{"state":"info","description":"","context":{"genre":"fluxcd","name":"/"}}]}`)) + f.Add("alakazam", "org/proj/_git/repo", "revision/dsa123a", "info", "", []byte{}, []byte(`{"count":0,"value":[]}`)) + f.Add("alakazam", "org/proj/_git/repo", "", "", "Progressing", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, urlSuffix, revision, severity, reason string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasSuffix(r.URL.Path, "_apis") { + w.Write([]byte(apiLocations)) + } else { + w.Write(response) + } + + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + azureDevOps, err := NewAzureDevOps(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert) + if err != nil { + return + } + + event := events.Event{} + + // Try to fuzz the event object, but if it fails (not enough seed), + // ignore it, as other inputs are also being used in this test. + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil && (revision != "") { + event.Metadata = map[string]string{ + "revision": revision, + } + } + event.Severity = severity + + _ = azureDevOps.Post(context.TODO(), event) + }) +} + func azStatus(state git.GitStatusState, context string, description string) *git.GitStatus { genre := "fluxcd" return &git.GitStatus{ diff --git a/internal/notifier/bitbucket_test.go b/internal/notifier/bitbucket_test.go index 519506eed..f4684b13a 100644 --- a/internal/notifier/bitbucket_test.go +++ b/internal/notifier/bitbucket_test.go @@ -17,8 +17,17 @@ limitations under the License. package notifier import ( + "context" + "crypto/x509" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/assert" ) @@ -38,3 +47,49 @@ func TestNewBitbucketInvalidToken(t *testing.T) { _, err := NewBitbucket("https://bitbucket.org/foo/bar", "bar", nil) assert.NotNil(t, err) } + +func FuzzBitbucket(f *testing.F) { + f.Add("user:pass", "org/repo", "revision/dsa123a", "info", []byte{}, []byte("{}")) + f.Add("user:pass", "org/repo", "revision/dsa123a", "error", []byte{}, []byte("{}")) + + f.Fuzz(func(t *testing.T, + token, urlSuffix, revision, severity string, seed, response []byte) { + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(io.Discard, r.Body) + w.Write(response) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + bitbucket, err := NewBitbucket(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert) + if err != nil { + return + } + + apiUrl, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("cannot parse api base URL: %v", err) + } + // Ensure the call does not go to bitbucket and fuzzes the response. + bitbucket.Client.SetApiBaseURL(*apiUrl) + + event := events.Event{} + + // Try to fuzz the event object, but if it fails (not enough seed), + // ignore it, as other inputs are also being used in this test. + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil && (revision != "") { + event.Metadata = map[string]string{ + "revision": revision, + } + } + event.Severity = severity + + _ = bitbucket.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/discord_test.go b/internal/notifier/discord_test.go index db15eaa45..26e472e5d 100644 --- a/internal/notifier/discord_test.go +++ b/internal/notifier/discord_test.go @@ -19,12 +19,15 @@ package notifier import ( "context" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "strings" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -49,3 +52,39 @@ func TestDiscord_Post(t *testing.T) { err = discord.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzDiscord(f *testing.F) { + f.Add("username", "channel", "/slack", "info", "update", []byte{}, []byte("{}")) + f.Add("", "channel", "", "error", "", []byte{}, []byte("")) + + f.Fuzz(func(t *testing.T, + username, channel, urlSuffix, severity, commitStatus string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(io.Discard, r.Body) + w.Write(response) + r.Body.Close() + })) + defer ts.Close() + + targetURL := fmt.Sprintf("%s/%s", ts.URL, urlSuffix) + discord, err := NewDiscord(targetURL, targetURL, username, channel) + if err != nil { + return + } + + event := events.Event{} + + // Try to fuzz the event object, but if it fails (not enough seed), + // ignore it, as other inputs are also being used in this test. + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Severity = severity + + _ = discord.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/forwarder_test.go b/internal/notifier/forwarder_test.go index c3d97ccca..c320af622 100644 --- a/internal/notifier/forwarder_test.go +++ b/internal/notifier/forwarder_test.go @@ -18,12 +18,15 @@ package notifier import ( "context" + "crypto/x509" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" @@ -52,3 +55,33 @@ func TestForwarder_Post(t *testing.T) { err = forwarder.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzForwarder(f *testing.F) { + f.Add("", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + urlSuffix string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + header := make(map[string]string) + _ = fuzz.NewConsumer(seed).FuzzMap(&header) + + forwarder, err := NewForwarder(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", header, &cert) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + _ = forwarder.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/github_test.go b/internal/notifier/github_test.go index c320df17d..396a2614c 100644 --- a/internal/notifier/github_test.go +++ b/internal/notifier/github_test.go @@ -17,8 +17,16 @@ limitations under the License. package notifier import ( + "context" + "crypto/x509" + "fmt" + "io" + "net/http" + "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/google/go-github/v41/github" "github.com/stretchr/testify/assert" ) @@ -69,6 +77,46 @@ func TestDuplicateGithubStatus(t *testing.T) { } } +func FuzzGitHub(f *testing.F) { + f.Add("token", "org/repo", "revision/abce1", "error", "", []byte{}, []byte(`[{"context":"/","state":"failure","description":""}]`)) + f.Add("token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/","state":"success","description":""}]`)) + f.Add("token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/","state":"failure","description":""}]`)) + f.Add("token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[]`)) + f.Add("token", "org/repo", "revision/abce1", "info", "Progressing", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, urlSuffix, revision, severity, reason string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + github, err := NewGitHub(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil && (revision != "") { + event.Metadata = map[string]string{ + "revision": revision, + } + } + + event.Severity = severity + event.Reason = reason + + _ = github.Post(context.TODO(), event) + }) +} + func ghStatus(state string, context string, description string) *github.RepoStatus { return &github.RepoStatus{ State: &state, diff --git a/internal/notifier/gitlab_test.go b/internal/notifier/gitlab_test.go index 32a50bdf9..2d4ece9cf 100644 --- a/internal/notifier/gitlab_test.go +++ b/internal/notifier/gitlab_test.go @@ -17,8 +17,16 @@ limitations under the License. package notifier import ( + "context" + "crypto/x509" + "fmt" + "io" + "net/http" + "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/assert" ) @@ -45,3 +53,42 @@ func TestNewGitLabEmptyToken(t *testing.T) { _, err := NewGitLab("https://gitlab.com/foo/bar", "", nil) assert.NotNil(t, err) } + +func FuzzGitLab(f *testing.F) { + f.Add("token", "org/repo", "revision/abce1", "error", "", []byte{}, []byte(`[{"sha":"abce1","status":"failed","name":"/","description":""}]`)) + f.Add("token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"sha":"abce1","status":"failed","name":"/","description":""}]`)) + f.Add("token", "org/repo", "revision/abce1", "info", "Progressing", []byte{}, []byte{}) + f.Add("token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[]`)) + + f.Fuzz(func(t *testing.T, + token, urlSuffix, revision, severity, reason string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + gitLab, err := NewGitLab(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil && (revision != "") { + event.Metadata = map[string]string{ + "revision": revision, + } + } + + event.Severity = severity + event.Reason = reason + + _ = gitLab.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/google_chat_test.go b/internal/notifier/google_chat_test.go index 8ca3074fc..2275ef96a 100644 --- a/internal/notifier/google_chat_test.go +++ b/internal/notifier/google_chat_test.go @@ -19,11 +19,14 @@ package notifier import ( "context" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -49,3 +52,36 @@ func TestGoogleChat_Post(t *testing.T) { err = google_chat.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzGoogleChat(f *testing.F) { + f.Add("", "error", "", "", []byte{}, []byte{}) + f.Add("", "info", "", "update", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + urlSuffix, severity, message, commitStatus string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + googlechat, err := NewGoogleChat(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "") + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Message = message + event.Severity = severity + + _ = googlechat.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/lark_test.go b/internal/notifier/lark_test.go index 50f07ac4a..038a690fc 100644 --- a/internal/notifier/lark_test.go +++ b/internal/notifier/lark_test.go @@ -8,6 +8,8 @@ import ( "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -30,3 +32,35 @@ func TestLark_Post(t *testing.T) { err = lark.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzLark(f *testing.F) { + f.Add("", "error", []byte{}, []byte{}) + f.Add("update", "error", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + commitStatus, severity string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + lark, err := NewLark(ts.URL) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Severity = severity + + _ = lark.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/matrix_test.go b/internal/notifier/matrix_test.go index ad8468521..c8e3eb4c2 100644 --- a/internal/notifier/matrix_test.go +++ b/internal/notifier/matrix_test.go @@ -1,9 +1,16 @@ package notifier import ( + "context" + "crypto/x509" + "fmt" + "io" + "net/http" + "net/http/httptest" "testing" "time" + fuzz "github.com/AdaLogics/go-fuzz-headers" "github.com/fluxcd/pkg/runtime/events" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -48,3 +55,34 @@ func TestSha1Sum(t *testing.T) { } } } + +func FuzzMatrix(f *testing.F) { + f.Add("token", "room1", "", "error", []byte{}, []byte{}) + f.Add("token", "room1", "", "info", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, roomId, urlSuffix, severity string, seed, response []byte) { + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + matrix, err := NewMatrix(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, roomId, &cert) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + event.Severity = severity + + _ = matrix.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/opsgenie_test.go b/internal/notifier/opsgenie_test.go index 9e5690f91..96732b2a0 100644 --- a/internal/notifier/opsgenie_test.go +++ b/internal/notifier/opsgenie_test.go @@ -18,12 +18,16 @@ package notifier import ( "context" + "crypto/x509" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -44,3 +48,38 @@ func TestOpsgenie_Post(t *testing.T) { err = opsgenie.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzOpsGenie(f *testing.F) { + f.Add("token", "", "", "error", "", []byte{}, []byte{}) + f.Add("token", "", "update", "info", "", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, urlSuffix, commitStatus, severity, message string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + opsgenie, err := NewOpsgenie(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert, token) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Message = message + + _ = opsgenie.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/rocket_test.go b/internal/notifier/rocket_test.go index bfddcfc36..df54fb46b 100644 --- a/internal/notifier/rocket_test.go +++ b/internal/notifier/rocket_test.go @@ -18,12 +18,16 @@ package notifier import ( "context" + "crypto/x509" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -46,3 +50,39 @@ func TestRocket_Post(t *testing.T) { err = rocket.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzRocket(f *testing.F) { + f.Add("user", "channel", "", "error", "", "", []byte{}, []byte{}) + f.Add("user", "channel", "", "error", "update", "", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + username, channel, urlSuffix, severity, commitStatus, message string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + rocket, err := NewRocket(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert, username, channel) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Severity = severity + event.Message = message + + _ = rocket.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/slack_test.go b/internal/notifier/slack_test.go index e9bcc5a72..f66ae2104 100644 --- a/internal/notifier/slack_test.go +++ b/internal/notifier/slack_test.go @@ -18,12 +18,16 @@ package notifier import ( "context" + "crypto/x509" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -56,3 +60,40 @@ func TestSlack_PostUpdate(t *testing.T) { err = slack.Post(context.TODO(), event) require.NoError(t, err) } + +func FuzzSlack(f *testing.F) { + f.Add("token", "user", "channel", "", "error", "", "", []byte{}, []byte{}) + f.Add("token", "", "channel", "", "info", "", "", []byte{}, []byte{}) + f.Add("token", "", "channel", "", "info", "update", "", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, username, channel, urlSuffix, severity, commitStatus, message string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + slack, err := NewSlack(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", token, &cert, username, channel) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Severity = severity + event.Message = message + + _ = slack.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/teams_test.go b/internal/notifier/teams_test.go index 2d5111db8..45add3912 100644 --- a/internal/notifier/teams_test.go +++ b/internal/notifier/teams_test.go @@ -18,12 +18,16 @@ package notifier import ( "context" + "crypto/x509" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -46,3 +50,40 @@ func TestTeams_Post(t *testing.T) { err = teams.Post(context.TODO(), testEvent()) require.NoError(t, err) } + +func FuzzMSTeams(f *testing.F) { + f.Add("token", "", "error", "", "", []byte{}, []byte{}) + f.Add("token", "", "info", "", "", []byte{}, []byte{}) + f.Add("token", "", "info", "", "update", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, urlSuffix, severity, message, commitStatus string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + teams, err := NewMSTeams(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Message = message + event.Severity = severity + + _ = teams.Post(context.TODO(), event) + }) +} diff --git a/internal/notifier/testdata/fuzz/FuzzDiscord/f00e373ef4651f2dc7c068fcac2826e42cf062e44d8ced6561aa0b92dafedd65 b/internal/notifier/testdata/fuzz/FuzzDiscord/f00e373ef4651f2dc7c068fcac2826e42cf062e44d8ced6561aa0b92dafedd65 new file mode 100644 index 000000000..28c6a83fa --- /dev/null +++ b/internal/notifier/testdata/fuzz/FuzzDiscord/f00e373ef4651f2dc7c068fcac2826e42cf062e44d8ced6561aa0b92dafedd65 @@ -0,0 +1,8 @@ +go test fuzz v1 +string("0") +string("0") +string("0") +string("0") +string("0") +[]byte("") +[]byte("00") diff --git a/internal/notifier/util_test.go b/internal/notifier/util_test.go index 397d0f8a6..b229f0683 100644 --- a/internal/notifier/util_test.go +++ b/internal/notifier/util_test.go @@ -19,6 +19,7 @@ package notifier import ( "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" @@ -123,3 +124,24 @@ func TestUtil_BasicAuth(t *testing.T) { s := basicAuth(username, password) require.Equal(t, "dXNlcjpwYXNzd29yZA==", s) } + +func Fuzz_Util_ParseGitAddress(f *testing.F) { + f.Add("ssh://git@abc.com") + + f.Fuzz(func(t *testing.T, gitAddress string) { + _, _, _ = parseGitAddress(gitAddress) + }) +} + +func Fuzz_Util_FormatNameAndDescription(f *testing.F) { + f.Add("aA1-", []byte{}) + + f.Fuzz(func(t *testing.T, reason string, seed []byte) { + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + event.Reason = reason + + _, _ = formatNameAndDescription(event) + }) +} diff --git a/internal/notifier/webex_test.go b/internal/notifier/webex_test.go index e8991e2d5..5b9428baf 100644 --- a/internal/notifier/webex_test.go +++ b/internal/notifier/webex_test.go @@ -18,12 +18,16 @@ package notifier import ( "context" + "crypto/x509" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/fluxcd/pkg/runtime/events" "github.com/stretchr/testify/require" ) @@ -54,3 +58,39 @@ func TestWebex_PostUpdate(t *testing.T) { err = webex.Post(context.TODO(), event) require.NoError(t, err) } + +func Fuzz_Webex(f *testing.F) { + f.Add("token", "channel", "", "error", "", "", []byte{}, []byte{}) + f.Add("token", "channel", "", "info", "", "update", []byte{}, []byte{}) + + f.Fuzz(func(t *testing.T, + token, channel, urlSuffix, severity, message, commitStatus string, seed, response []byte) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(response) + io.Copy(io.Discard, r.Body) + r.Body.Close() + })) + defer ts.Close() + + var cert x509.CertPool + _ = fuzz.NewConsumer(seed).GenerateStruct(&cert) + + webex, err := NewWebex(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert, channel, token) + if err != nil { + return + } + + event := events.Event{} + _ = fuzz.NewConsumer(seed).GenerateStruct(&event) + + if event.Metadata == nil { + event.Metadata = map[string]string{} + } + + event.Metadata["commit_status"] = commitStatus + event.Message = message + event.Severity = severity + + _ = webex.Post(context.TODO(), event) + }) +} diff --git a/tests/fuzz/alertmanager_fuzzer.go b/tests/fuzz/alertmanager_fuzzer.go deleted file mode 100644 index 81cc42e0d..000000000 --- a/tests/fuzz/alertmanager_fuzzer.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzAlertmanager implements a fuzzer that targets Alertmanager.Post(). -func FuzzAlertmanager(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - alertmanager, err := NewAlertmanager(ts.URL, "", nil) - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = alertmanager.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/azure_devops_fuzzer.go b/tests/fuzz/azure_devops_fuzzer.go deleted file mode 100644 index 621e0bff1..000000000 --- a/tests/fuzz/azure_devops_fuzzer.go +++ /dev/null @@ -1,59 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzAzureDevOps implements a fuzzer that targets AzureDevOps.Post(). -func FuzzAzureDevOps(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - token, err := f.GetString() - if err != nil { - return 0 - } - - azureDevOps, err := NewAzureDevOps(ts.URL, token, nil) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = azureDevOps.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/bitbucket_fuzzer.go b/tests/fuzz/bitbucket_fuzzer.go deleted file mode 100644 index d0e8e1cac..000000000 --- a/tests/fuzz/bitbucket_fuzzer.go +++ /dev/null @@ -1,59 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzBitbucket implements a fuzzer that targets Bitbucket.Post(). -func FuzzBitbucket(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - token, err := f.GetString() - if err != nil { - return 0 - } - - bitbucket, err := NewBitbucket(ts.URL, token, nil) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = bitbucket.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/discord_fuzzer.go b/tests/fuzz/discord_fuzzer.go deleted file mode 100644 index 9cebf5715..000000000 --- a/tests/fuzz/discord_fuzzer.go +++ /dev/null @@ -1,64 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzDiscord implements a fuzzer that targets Discord.Post(). -func FuzzDiscord(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - username, err := f.GetString() - if err != nil { - return 0 - } - - channel, err := f.GetString() - if err != nil { - return 0 - } - - discord, err := NewDiscord(ts.URL, "", username, channel) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = discord.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/forwarder_fuzzer.go b/tests/fuzz/forwarder_fuzzer.go deleted file mode 100644 index b045fa321..000000000 --- a/tests/fuzz/forwarder_fuzzer.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzForwarder implements a fuzzer that targets Forwarder.Post(). -func FuzzForwarder(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - header := make(map[string]string) - forwarder, err := NewForwarder(ts.URL, "", header, nil) - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = forwarder.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/github_fuzzer.go b/tests/fuzz/github_fuzzer.go deleted file mode 100644 index 56917c36c..000000000 --- a/tests/fuzz/github_fuzzer.go +++ /dev/null @@ -1,59 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzGitHub implements a fuzzer that targets GitHub.Post(). -func FuzzGitHub(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - token, err := f.GetString() - if err != nil { - return 0 - } - - github, err := NewGitHub(ts.URL, token, nil) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = github.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/gitlab_fuzzer.go b/tests/fuzz/gitlab_fuzzer.go deleted file mode 100644 index 03fc6eb48..000000000 --- a/tests/fuzz/gitlab_fuzzer.go +++ /dev/null @@ -1,59 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzGitLab implements a fuzzer that targets GitLab.Post(). -func FuzzGitLab(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - token, err := f.GetString() - if err != nil { - return 0 - } - - gitLab, err := NewGitLab(ts.URL, token, nil) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = gitLab.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/go.mod b/tests/fuzz/go.mod deleted file mode 100644 index a517047c0..000000000 --- a/tests/fuzz/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module github.com/fluxcd/notification-controller/tests/fuzz - -// This module is used only to avoid polluting the main module -// with fuzz dependencies. - -go 1.17 - -replace ( - github.com/fluxcd/notification-controller/api => ../../api - github.com/fluxcd/notification-controller => ../../ -) diff --git a/tests/fuzz/google_chat_fuzzer.go b/tests/fuzz/google_chat_fuzzer.go deleted file mode 100644 index e4fc68e65..000000000 --- a/tests/fuzz/google_chat_fuzzer.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzGoogleChat implements a fuzzer that targets GoogleChat.Post(). -func FuzzGoogleChat(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - googlechat, err := NewGoogleChat(ts.URL, "") - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = googlechat.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/lark_fuzzer.go b/tests/fuzz/lark_fuzzer.go deleted file mode 100644 index 2e055492c..000000000 --- a/tests/fuzz/lark_fuzzer.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzLark implements a fuzzer that targets Lark.Post(). -func FuzzLark(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - lark, err := NewLark(ts.URL) - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = lark.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/matrix_fuzzer.go b/tests/fuzz/matrix_fuzzer.go deleted file mode 100644 index 4bcff2cae..000000000 --- a/tests/fuzz/matrix_fuzzer.go +++ /dev/null @@ -1,59 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzMatrix implements a fuzzer that targets Matrix.Post(). -func FuzzMatrix(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - token, err := f.GetString() - if err != nil { - return 0 - } - - matrix, err := NewMatrix(ts.URL, "", token, nil) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = matrix.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/native_go_run.sh b/tests/fuzz/native_go_run.sh new file mode 100755 index 000000000..55f98b5f9 --- /dev/null +++ b/tests/fuzz/native_go_run.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Copyright 2022 The Flux authors +# +# 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. + +set -euxo pipefail + +# This script iterates through all go fuzzing targets, running each one +# through the period of time established by FUZZ_TIME. + +FUZZ_TIME=${FUZZ_TIME:-"5s"} + +test_files=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' .) + +for file in ${test_files} +do + targets=$(grep -oP 'func \K(Fuzz\w*)' "${file}") + for target_name in ${targets} + do + echo "Running ${file}.${target_name} for ${FUZZ_TIME}." + file_dir=$(dirname "${file}") + + go test -fuzz="${target_name}" -fuzztime "${FUZZ_TIME}" "${file_dir}" + done +done diff --git a/tests/fuzz/opsgenie_fuzzer.go b/tests/fuzz/opsgenie_fuzzer.go deleted file mode 100644 index db6c6c979..000000000 --- a/tests/fuzz/opsgenie_fuzzer.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzOpsGenie implements a fuzzer that targets Opsgenie.Post(). -func FuzzOpsGenie(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - opsgenie, err := NewOpsgenie(ts.URL, "", nil, "token") - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = opsgenie.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/oss_fuzz_build.sh b/tests/fuzz/oss_fuzz_build.sh index 771236179..247d9b1fb 100755 --- a/tests/fuzz/oss_fuzz_build.sh +++ b/tests/fuzz/oss_fuzz_build.sh @@ -19,48 +19,61 @@ set -euxo pipefail GOPATH="${GOPATH:-/root/go}" GO_SRC="${GOPATH}/src" PROJECT_PATH="github.com/fluxcd/notification-controller" +TMP_DIR=$(mktemp -d /tmp/oss_fuzz-XXXXXX) -cd "${GO_SRC}" - -# Move fuzzer to their respective directories. -# This removes dependency noises from the modules' go.mod and go.sum files. -cp "${PROJECT_PATH}/tests/fuzz/util_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/alertmanager_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/opsgenie_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/webex_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/discord_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/forwarder_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/lark_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/matrix_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/rocket_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/slack_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/teams_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/google_chat_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/azure_devops_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/bitbucket_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/github_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" -cp "${PROJECT_PATH}/tests/fuzz/gitlab_fuzzer.go" "${PROJECT_PATH}/internal/notifier/" - - -# compile fuzz tests for the runtime module -pushd "${PROJECT_PATH}" - -go get -d github.com/AdaLogics/go-fuzz-headers -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzNotifierUtil fuzz_notifier_util -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzAlertmanager fuzz_alert_manager -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzOpsGenie fuzz_opsgenie -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzWebex fuzz_webex -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzDiscord fuzz_discord -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzForwarder fuzz_forwarder -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzLark fuzz_lark -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzMatrix fuzz_matrix -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzRocket fuzz_rocket -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzSlack fuzz_slack -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzMSTeams fuzz_msteams -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzGoogleChat fuzz_google_chat -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzAzureDevOps fuzz_azure_devops -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzBitbucket fuzz_bitbucket -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzGitHub fuzz_github -compile_go_fuzzer "${PROJECT_PATH}/internal/notifier/" FuzzGitLab fuzz_gitlab - -popd +cleanup(){ + rm -rf "${TMP_DIR}" +} +trap cleanup EXIT + +install_deps(){ + if ! command -v go-118-fuzz-build &> /dev/null || ! command -v addimport &> /dev/null; then + mkdir -p "${TMP_DIR}/go-118-fuzz-build" + + git clone https://github.com/AdamKorcz/go-118-fuzz-build "${TMP_DIR}/go-118-fuzz-build" + cd "${TMP_DIR}/go-118-fuzz-build" + go build -o "${GOPATH}/bin/go-118-fuzz-build" + + cd addimport + go build -o "${GOPATH}/bin/addimport" + fi + + if ! command -v goimports &> /dev/null; then + go install golang.org/x/tools/cmd/goimports@latest + fi +} + +# Removes the content of test funcs which could cause the Fuzz +# tests to break. +remove_test_funcs(){ + filename=$1 + + echo "removing co-located *testing.T" + sed -i -e '/func Test.*testing.T) {$/ {:r;/\n}/!{N;br}; s/\n.*\n/\n/}' "${filename}" + + # After removing the body of the go testing funcs, consolidate the imports. + goimports -w "${filename}" +} + +install_deps + +cd "${GO_SRC}/${PROJECT_PATH}" + +go get github.com/AdamKorcz/go-118-fuzz-build/utils + +# Iterate through all Go Fuzz targets, compiling each into a fuzzer. +test_files=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' .) +for file in ${test_files} +do + remove_test_funcs "${file}" + + targets=$(grep -oP 'func \K(Fuzz\w*)' "${file}") + for target_name in ${targets} + do + fuzzer_name=$(echo "${target_name}" | tr '[:upper:]' '[:lower:]') + target_dir=$(dirname "${file}") + + echo "Building ${file}.${target_name} into ${fuzzer_name}" + compile_native_go_fuzzer "${target_dir}" "${target_name}" "${fuzzer_name}" + done +done diff --git a/tests/fuzz/rocket_fuzzer.go b/tests/fuzz/rocket_fuzzer.go deleted file mode 100644 index 8035f991b..000000000 --- a/tests/fuzz/rocket_fuzzer.go +++ /dev/null @@ -1,64 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzRocket implements a fuzzer that targets Rocket.Post(). -func FuzzRocket(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - username, err := f.GetString() - if err != nil { - return 0 - } - - channel, err := f.GetString() - if err != nil { - return 0 - } - - rocket, err := NewRocket(ts.URL, "", nil, username, channel) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = rocket.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/slack_fuzzer.go b/tests/fuzz/slack_fuzzer.go deleted file mode 100644 index a165b2961..000000000 --- a/tests/fuzz/slack_fuzzer.go +++ /dev/null @@ -1,69 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzSlack implements a fuzzer that targets Slack.Post(). -func FuzzSlack(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - f := fuzz.NewConsumer(data) - username, err := f.GetString() - if err != nil { - return 0 - } - - channel, err := f.GetString() - if err != nil { - return 0 - } - - token, err := f.GetString() - if err != nil { - return 0 - } - - slack, err := NewSlack(ts.URL, "", token, nil, username, channel) - if err != nil { - return 0 - } - - event := events.Event{} - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = slack.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/teams_fuzzer.go b/tests/fuzz/teams_fuzzer.go deleted file mode 100644 index 4e90e25ed..000000000 --- a/tests/fuzz/teams_fuzzer.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzMSTeams implements a fuzzer that targets MSTeams.Post(). -func FuzzMSTeams(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - teams, err := NewMSTeams(ts.URL, "", nil) - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = teams.Post(context.TODO(), event) - - return 1 -} diff --git a/tests/fuzz/util_fuzzer.go b/tests/fuzz/util_fuzzer.go deleted file mode 100644 index 2552c0f9c..000000000 --- a/tests/fuzz/util_fuzzer.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2021 The Flux authors - -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. -*/ - -package notifier - -import ( - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzNotifierUtil implements a fuzzer that targets -// notifier.formatNameAndDescription() and notifier.parseGitAddress(). -func FuzzNotifierUtil(data []byte) int { - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _, _ = formatNameAndDescription(event) - _, _, _ = parseGitAddress(string(data)) - - return 1 -} diff --git a/tests/fuzz/webex_fuzzer.go b/tests/fuzz/webex_fuzzer.go deleted file mode 100644 index 6fbbde1f4..000000000 --- a/tests/fuzz/webex_fuzzer.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -/* -Copyright 2022 The Flux authors - -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. -*/ - -package notifier - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - - fuzz "github.com/AdaLogics/go-fuzz-headers" - "github.com/fluxcd/pkg/runtime/events" -) - -// FuzzWebex implements a fuzzer that targets Webex.Post(). -func FuzzWebex(data []byte) int { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - io.ReadAll(r.Body) - r.Body.Close() - })) - defer ts.Close() - - webex, err := NewWebex(ts.URL, "", nil, "", "") - if err != nil { - return 0 - } - - f := fuzz.NewConsumer(data) - event := events.Event{} - - if err := f.GenerateStruct(&event); err != nil { - return 0 - } - - _ = webex.Post(context.TODO(), event) - - return 1 -}