Skip to content

Commit

Permalink
Update fuzz tests to use go fuzz features (#148)
Browse files Browse the repository at this point in the history
* added two fuzz tests for parser functionality

* ran test for v7 generation that was accidentally excluded

* added fuzz tests for FromBinary family of functions, moved to the codec_tests.go file

* refined logic for FromX fuzz functions

* fixed logical errors with fuzz tests

* removed harden from some other github actions workflows

* fix missing codecov token

* Apply suggestions from code review

* fixed code review feedback

* Update .github/workflows/go.yml
  • Loading branch information
cameracker authored Jun 28, 2024
1 parent 56e03f7 commit bb31fe5
Show file tree
Hide file tree
Showing 48 changed files with 104 additions and 133 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ jobs:
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Harden Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
with:
egress-policy: audit

- name: 'Checkout Repository'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: 'Dependency Review'
Expand Down
16 changes: 3 additions & 13 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ jobs:
env:
GO111MODULE: auto
steps:

- name: Harden Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
with:
egress-policy: audit

- name: Build
uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with:
Expand All @@ -38,20 +32,16 @@ jobs:
run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic

- name: Coverage
uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

build-legacy:
name: Build + Test Previous Stable
runs-on: ubuntu-latest
env:
GO111MODULE: auto
steps:

- name: Harden Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
with:
egress-policy: audit

- name: Build
uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with:
Expand Down
121 changes: 100 additions & 21 deletions codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ package uuid

import (
"bytes"
"flag"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
)
Expand Down Expand Up @@ -403,28 +400,110 @@ func BenchmarkParseV4(b *testing.B) {
}
}

var seedFuzzCorpus = flag.Bool("seed_fuzz_corpus", false, "seed fuzz test corpus")
const uuidPattern = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"

func TestSeedFuzzCorpus(t *testing.T) {
// flag.Parse() is called for us by the test binary.
if !*seedFuzzCorpus {
t.Skip("seeding fuzz test corpus only on demand")
var fromBytesCorpus = [][]byte{
{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8},
{4, 8, 15, 16, 23, 42},
}

// FuzzFromBytesFunc is a fuzz testing suite that exercises the FromBytes function
func FuzzFromBytesFunc(f *testing.F) {
for _, seed := range fromBytesCorpus {
f.Add(seed)
}
corpusDir := filepath.Join(".", "testdata", "corpus")
writeSeedFile := func(name, data string) error {
path := filepath.Join(corpusDir, name)
return os.WriteFile(path, []byte(data), os.ModePerm)
uuidRegexp, err := regexp.Compile(uuidPattern)
if err != nil {
f.Fatal("uuid regexp failed to compile")
}
for _, fst := range fromStringTests {
name := "seed_valid_" + fst.variant
if err := writeSeedFile(name, fst.input); err != nil {
t.Fatal(err)
f.Fuzz(func(t *testing.T, payload []byte) {
u, err := FromBytes(payload)
if len(payload) != Size && err == nil {
t.Errorf("%v did not result in an error", payload)
}
if len(payload) == Size && u == Nil {
t.Errorf("%v resulted in Nil uuid", payload)
}
if len(payload) == Size && !uuidRegexp.MatchString(u.String()) {
t.Errorf("%v resulted in invalid uuid %s", payload, u.String())
}
// otherwise, allow to pass if no panic
})
}

// FuzzFromBytesOrNilFunc is a fuzz testing suite that exercises the FromBytesOrNil function
func FuzzFromBytesOrNilFunc(f *testing.F) {
for _, seed := range fromBytesCorpus {
f.Add(seed)
}
for i, s := range invalidFromStringInputs {
name := fmt.Sprintf("seed_invalid_%d", i)
if err := writeSeedFile(name, s); err != nil {
t.Fatal(err)
uuidRegexp, err := regexp.Compile(uuidPattern)
if err != nil {
f.Error("uuid regexp failed to compile")
}
f.Fuzz(func(t *testing.T, payload []byte) {
u := FromBytesOrNil(payload)
if len(payload) != Size && u != Nil {
t.Errorf("%v resulted in non Nil uuid %s", payload, u.String())
}
if len(payload) == Size && u == Nil {
t.Errorf("%v resulted Nil uuid", payload)
}
if len(payload) == Size && !uuidRegexp.MatchString(u.String()) {
t.Errorf("%v resulted in invalid uuid %s", payload, u.String())
}
// otherwise, allow to pass if no panic
})
}

var fromStringCorpus = []string{
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"6BA7B810-9DAD-11D1-80B4-00C04FD430C8",
"{6BA7B810-9DAD-11D1-80B4-00C04FD430C8}",
"urn:uuid:6BA7B810-9DAD-11D1-80B4-00C04FD430C8",
"6BA7B8109DAD11D180B400C04FD430C8",
"{6BA7B8109DAD11D180B400C04FD430C8}",
"urn:uuid:6BA7B8109DAD11D180B400C04FD430C8",
}

// FuzzFromStringFunc is a fuzz testing suite that exercises the FromString function
func FuzzFromStringFunc(f *testing.F) {
for _, seed := range fromStringCorpus {
f.Add(seed)
}
uuidRegexp, err := regexp.Compile(uuidPattern)
if err != nil {
f.Fatal("uuid regexp failed to compile")
}
f.Fuzz(func(t *testing.T, payload string) {
u, err := FromString(payload)
if err != nil {
if u == Nil {
t.Errorf("%s resulted in Nil uuid", payload)
}
if !uuidRegexp.MatchString(u.String()) {
t.Errorf("%s resulted in invalid uuid %s", payload, u.String())
}
}
// otherwise, allow to pass if no panic
})
}

// FuzzFromStringOrNil is a fuzz testing suite that exercises the FromStringOrNil function
func FuzzFromStringOrNilFunc(f *testing.F) {
for _, seed := range fromStringCorpus {
f.Add(seed)
}
uuidRegexp, err := regexp.Compile(uuidPattern)
if err != nil {
f.Error("uuid regexp failed to compile")
}
f.Fuzz(func(t *testing.T, payload string) {
u := FromStringOrNil(payload)
if u != Nil {
if !uuidRegexp.MatchString(u.String()) {
t.Errorf("%s resulted in invalid uuid %s", payload, u.String())
}
}
// otherwise, allow to pass if no panic
})
}
48 changes: 0 additions & 48 deletions fuzz.go

This file was deleted.

1 change: 1 addition & 0 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ func testNewV7(t *testing.T) {
t.Run("FaultyRand", makeTestNewV7FaultyRand())
t.Run("FaultyRandWithOptions", makeTestNewV7FaultyRandWithOptions())
t.Run("ShortRandomRead", makeTestNewV7ShortRandomRead())
t.Run("ShortRandomReadWithOptions", makeTestNewV7ShortRandomReadWithOptions())
t.Run("KSortable", makeTestNewV7KSortable())
t.Run("ClockSequence", makeTestNewV7ClockSequence())
}
Expand Down
1 change: 0 additions & 1 deletion testdata/corpus/1416586f4a34d02bcb506f6107b40df512b9f2f9

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/3b46a7e7b02ec193581e6c9fa2c8a72f50a64e08-1

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/50c54bb75fcfdc488f162bf2f0c6dec6103bfa18-5

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/69c581ab749cbd56be8684d3a58ac2cfab9af0f4-5

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/752bf000e0bff06777dd0d6f0be6353844de678a-3

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/a4483762d4ece8466d82cca5cacd35a0829c4e60-2

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/d0952c45e0c823fc5cc12bcf7d9b877d150ab523-1

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion testdata/corpus/e2b84d2065846891f18ae109b12e01d224e1c7c3-4

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/e320d749435115e874f77420e17d0937e07f69f3-2

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/ed132d47d757f6468443a22df8a2a965efb34098-7

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/eeefb01f7bb3c627aedb292c994b20f739ffd613-6

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_0

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_1

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_10

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_11

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_12

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_13

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_14

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_15

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_16

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_17

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_18

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_19

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_2

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_20

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_21

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_22

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_23

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_3

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_4

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_5

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_6

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_7

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_8

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_invalid_9

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_valid_BracedCanonical

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_valid_BracedHashlike

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_valid_Canonical

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_valid_Hashlike

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_valid_URNCanonical

This file was deleted.

1 change: 0 additions & 1 deletion testdata/corpus/seed_valid_URNHashlike

This file was deleted.

0 comments on commit bb31fe5

Please sign in to comment.