# TODO(jayconrod): support shared memory on more platforms.
[!darwin] [!linux] [!windows] skip

# Tests that a crash caused by a mutator-discovered input writes the bad input
# to testdata, and fails+reports correctly. This tests the end-to-end behavior
# of the mutator finding a crash while fuzzing, adding it as a regression test
# to the seed corpus in testdata, and failing the next time the test is run.

[short] skip

# Running the seed corpus for all of the targets should pass the first
# time, since nothing in the seed corpus will cause a crash.
go test

# Running the fuzzer should find a crashing input quickly.
! go test -fuzz=FuzzWithBug -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithBug[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzWithBug

# Now, the failing bytes should have been added to the seed corpus for
# the target, and should fail when run without fuzzing.
! go test
stdout 'testdata[/\\]fuzz[/\\]FuzzWithBug[/\\][a-f0-9]{64}'
stdout 'this input caused a crash!'

! go test -run=FuzzWithNilPanic -fuzz=FuzzWithNilPanic -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithNilPanic[/\\]'
stdout 'runtime.Goexit'
go run check_testdata.go FuzzWithNilPanic

! go test -run=FuzzWithFail -fuzz=FuzzWithFail -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithFail[/\\]'
go run check_testdata.go FuzzWithFail

! go test -run=FuzzWithLogFail -fuzz=FuzzWithLogFail -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithLogFail[/\\]'
stdout 'logged something'
go run check_testdata.go FuzzWithLogFail

! go test -run=FuzzWithErrorf -fuzz=FuzzWithErrorf -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithErrorf[/\\]'
stdout 'errorf was called here'
go run check_testdata.go FuzzWithErrorf

! go test -run=FuzzWithFatalf -fuzz=FuzzWithFatalf -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithFatalf[/\\]'
stdout 'fatalf was called here'
go run check_testdata.go FuzzWithFatalf

! go test -run=FuzzWithBadExit -fuzz=FuzzWithBadExit -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithBadExit[/\\]'
stdout 'unexpectedly'
go run check_testdata.go FuzzWithBadExit

# Running the fuzzer should find a crashing input quickly for fuzzing two types.
! go test -run=FuzzWithTwoTypes -fuzz=FuzzWithTwoTypes -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzWithTwoTypes[/\\]'
stdout 'these inputs caused a crash!'
go run check_testdata.go FuzzWithTwoTypes

# Running the fuzzer should find a crashing input quickly for an integer.
! go test -run=FuzzInt -fuzz=FuzzInt -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzInt[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzInt

! go test -run=FuzzUint -fuzz=FuzzUint -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzUint[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzUint

# Running the fuzzer should find a crashing input quickly for a bool.
! go test -run=FuzzBool -fuzz=FuzzBool -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzBool[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzBool

# Running the fuzzer should find a crashing input quickly for a float.
! go test -run=FuzzFloat -fuzz=FuzzFloat -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzFloat[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzFloat

# Running the fuzzer should find a crashing input quickly for a byte.
! go test -run=FuzzByte -fuzz=FuzzByte -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzByte[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzByte

# Running the fuzzer should find a crashing input quickly for a rune.
! go test -run=FuzzRune -fuzz=FuzzRune -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzRune[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzRune

# Running the fuzzer should find a crashing input quickly for a string.
! go test -run=FuzzString -fuzz=FuzzString -fuzztime=100x -fuzzminimizetime=1000x
stdout 'testdata[/\\]fuzz[/\\]FuzzString[/\\]'
stdout 'this input caused a crash!'
go run check_testdata.go FuzzString

-- go.mod --
module m

go 1.16
-- fuzz_crash_test.go --
package fuzz_crash

import (
    "os"
	"testing"
)

func FuzzWithBug(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			panic("this input caused a crash!")
		}
	})
}

func FuzzWithNilPanic(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			panic(nil)
		}
	})
}

func FuzzWithFail(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			t.Fail()
		}
	})
}

func FuzzWithLogFail(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			t.Log("logged something")
			t.Fail()
		}
	})
}

func FuzzWithErrorf(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			t.Errorf("errorf was called here")
		}
	})
}

func FuzzWithFatalf(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			t.Fatalf("fatalf was called here")
		}
	})
}

func FuzzWithBadExit(f *testing.F) {
	f.Add([]byte("aa"))
	f.Fuzz(func(t *testing.T, b []byte) {
		if string(b) != "aa" {
			os.Exit(1)
		}
	})
}

func FuzzWithTwoTypes(f *testing.F) {
	f.Fuzz(func(t *testing.T, a, b []byte) {
		if len(a) > 0 && len(b) > 0 {
			panic("these inputs caused a crash!")
		}
	})
}

func FuzzInt(f *testing.F) {
	f.Add(0)
	f.Fuzz(func(t *testing.T, a int) {
		if a != 0 {
			panic("this input caused a crash!")
		}
	})
}

func FuzzUint(f *testing.F) {
	f.Add(uint(0))
	f.Fuzz(func(t *testing.T, a uint) {
		if a != 0 {
			panic("this input caused a crash!")
		}
	})
}

func FuzzBool(f *testing.F) {
	f.Add(false)
	f.Fuzz(func(t *testing.T, a bool) {
		if a {
			panic("this input caused a crash!")
		}
	})
}

func FuzzFloat(f *testing.F) {
	f.Fuzz(func(t *testing.T, a float64) {
		if a != float64(int64(a)) {
			// It has a decimal, so it was mutated by division
			panic("this input caused a crash!")
		}
	})
}

func FuzzByte(f *testing.F) {
	f.Add(byte(0))
	f.Fuzz(func(t *testing.T, a byte) {
		if a != 0 {
			panic("this input caused a crash!")
		}
	})
}

func FuzzRune(f *testing.F) {
	f.Add(rune(0))
	f.Fuzz(func(t *testing.T, a rune) {
		if a != 0 {
			panic("this input caused a crash!")
		}
	})
}

func FuzzString(f *testing.F) {
	f.Add("")
	f.Fuzz(func(t *testing.T, a string) {
		if a != "" {
			panic("this input caused a crash!")
		}
	})
}

-- check_testdata.go --
// +build ignore

package main

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
)

func main() {
	target := os.Args[1]
	dir := filepath.Join("testdata/fuzz", target)

	files, err := ioutil.ReadDir(dir)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if len(files) == 0 {
		fmt.Fprintf(os.Stderr, "expect at least one new mutation to be written to testdata\n")
		os.Exit(1)
	}

	fname := files[0].Name()
	contents, err := ioutil.ReadFile(filepath.Join(dir, fname))
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if bytes.Equal(contents, []byte("aa")) {
		fmt.Fprintf(os.Stderr, "newly written testdata entry was not mutated\n")
		os.Exit(1)
	}
	// The hash of the bytes in the file should match the filename.
	h := []byte(fmt.Sprintf("%x", sha256.Sum256(contents)))
	if !bytes.Equal([]byte(fname), h) {
		fmt.Fprintf(os.Stderr, "hash of bytes %q does not match filename %q\n", h, fname)
		os.Exit(1)
	}
}
