Slide 1

Slide 1 text

G tt ng ta te w th f zz ng L di la P sk ve , P od ct oa d L v P c, P b - @a - m #7, 3 .5.2 1

Slide 2

Slide 2 text

W at s uz in ? L v P c, P b - @a - m #7, 3 .5.2 2

Slide 3

Slide 3 text

4 g .d /d /f / L v P c, P b - @a - m #7, 3 .5.2 3

Slide 4

Slide 4 text

R qu re en s (05/2022) - go 1.18+ - AMD64 and ARM64 architectures only L v P c, P b - @a - m #7, 3 .5.2 4

Slide 5

Slide 5 text

T pe a gu en s 4 T f a t a l h f n t : string, []byte int, int8, int16, int32/rune, int64 uint, uint8/byte, uint16, uint32, uint64 float32, float64 bool 4 h ://g .c /t s/f - a l t c s , i c L v P c, P b - @a - m #7, 3 .5.2 5

Slide 6

Slide 6 text

W y o ou an t u e f zz ng? L v P c, P b - @a - m #7, 3 .5.2 6

Slide 7

Slide 7 text

O S-F zz C l , O -F 3 s s C/C++, R , G , P a J /J c . O l e s e V m r t . O -F s s f x _6 n i b . 4 A J 2 , O -F a f e 3 ,0 b 5 e s p s. 3 h ://g .c /g /o -f L v P c, P b - @a - m #7, 3 .5.2 7

Slide 8

Slide 8 text

G uz W s b a t , n G , z (r y m ) m o e c e g p s. u p 1 p e 2 A . t , f 8 p s u c e g i f o -s s e. — L S 1 W e F ? D n C e g i M R i L v P c, P b - @a - m #7, 3 .5.2 8

Slide 9

Slide 9 text

T pe o B gs 4 C , T s n H 4 M C i e k o o n l 4 R C o 4 E v R e C t 4 U e e o 4 U n B r T r g a z t a e d r n c : u a t s n c , c m , m o . s s h a t t g s k e 5 % l C 2 2 h ://b .f z.i /w -i -f -t / L v P c, P b - @a - m #7, 3 .5.2 9

Slide 10

Slide 10 text

W at ho ld F zz? I p e, t b i a m h r o : 4 P y e A 4 E d s e (p a c n t o r n s ) 4 C r & e i c 4 E l i c D e n C u n 4 M , a i n o o a t 4 I i C S 4 P & m l o t , v n a p l L v P c, P b - @a - m #7, 3 .5.2 1

Slide 11

Slide 11 text

F zz ut ri l 4 h ://g .d /d /t l/f 4 F g y L v P c, P b - @a - m #7, 3 .5.2 1

Slide 12

Slide 12 text

func Reverse(s string) string { b := []byte(s) for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 { b[i], b[j] = b[j], b[i] } return string(b) } L v P c, P b - @a - m #7, 3 .5.2 1

Slide 13

Slide 13 text

go run main.go original: "The quick brown fox jumped over the lazy dog" reversed: "god yzal eht revo depmuj xof nworb kciuq ehT" reversed again: "The quick brown fox jumped over the lazy dog" L v P c, P b - @a - m #7, 3 .5.2 1

Slide 14

Slide 14 text

func TestReverse(t *testing.T) { testcases := []struct { in, want string }{ {"Hello, world", "dlrow ,olleH"}, {" ", " "}, {"!12345", "54321!"}, } for _, tc := range testcases { rev := Reverse(tc.in) if rev != tc.want { t.Errorf("Reverse: %q, want %q", rev, tc.want) } } } L v P c, P b - @a - m #7, 3 .5.2 1

Slide 15

Slide 15 text

$ go test PASS ok github.com/abtris/golang-meetup-7-fuzz-demo/fuzz 0.095s L v P c, P b - @a - m #7, 3 .5.2 1

Slide 16

Slide 16 text

func FuzzReverse(f *testing.F) { testcases := []string{"Hello, world", " ", "!12345"} for _, tc := range testcases { f.Add(tc) // Use f.Add to provide a seed corpus } f.Fuzz(func(t *testing.T, orig string) { rev := Reverse(orig) doubleRev := Reverse(rev) if orig != doubleRev { t.Errorf("Before: %q, after: %q", orig, doubleRev) } if utf8.ValidString(orig) && !utf8.ValidString(rev) { t.Errorf("Reverse produced invalid UTF-8 string %q", rev) } }) } L v P c, P b - @a - m #7, 3 .5.2 1

Slide 17

Slide 17 text

$ go test -fuzz=Fuzz fuzz: elapsed: 0s, gathering baseline coverage: 0/47 completed fuzz: minimizing 43-byte failing input file fuzz: elapsed: 0s, gathering baseline coverage: 8/47 completed --- FAIL: FuzzReverse (0.03s) --- FAIL: FuzzReverse (0.00s) reverse_test.go:36: Reverse produced invalid UTF-8 string "\x81\xcc" Failing input written to testdata/fuzz/FuzzReverse/287eb9f2ef9b6220c30be65d3f291f4816b296dbd9a859172e648d6cce979cbb To re-run: go test -run=FuzzReverse/287eb9f2ef9b6220c30be65d3f291f4816b296dbd9a859172e648d6cce979cbb FAIL exit status 1 FAIL github.com/abtris/golang-meetup-7-fuzz-demo/fuzz 0.250s L v P c, P b - @a - m #7, 3 .5.2 1

Slide 18

Slide 18 text

W er i p ob em? reverse_test.go:36: Reverse produced invalid UTF-8 string "\x81\xcc" L v P c, P b - @a - m #7, 3 .5.2 1

Slide 19

Slide 19 text

S ri gs, b te , r ne a d ha ac er i G V r r w s c s e y v U -8-e r . — utf8.ValidString L v P c, P b - @a - m #7, 3 .5.2 1

Slide 20

Slide 20 text

L t's eb g func FuzzReverse(f *testing.F) { testcases := []string{"Hello, world", " ", "!12345"} for _, tc := range testcases { f.Add(tc) // Use f.Add to provide a seed corpus } f.Fuzz(func(t *testing.T, orig string) { rev := Reverse(orig) doubleRev := Reverse(rev) t.Logf("Number of runes: orig=%d, rev=%d, doubleRev=%d", utf8.RuneCountInString(orig), utf8.RuneCountInString(rev), utf8.RuneCountInString(doubleRev)) if orig != doubleRev { t.Errorf("Before: %q, after: %q", orig, doubleRev) } if utf8.ValidString(orig) && !utf8.ValidString(rev) { t.Errorf("Reverse produced invalid UTF-8 string %q", rev) } }) } L v P c, P b - @a - m #7, 3 .5.2 2

Slide 21

Slide 21 text

L t's eb g $ go test -fuzz=Fuzz fuzz: elapsed: 0s, gathering baseline coverage: 0/49 completed failure while testing seed corpus entry: FuzzReverse/287eb9f2ef9b6220c30be65d3f291f4816b296dbd9a859172e648d6cce979cbb fuzz: elapsed: 0s, gathering baseline coverage: 3/49 completed --- FAIL: FuzzReverse (0.01s) --- FAIL: FuzzReverse (0.00s) reverse_test.go:32: Number of runes: orig=1, rev=2, doubleRev=1 reverse_test.go:38: Reverse produced invalid UTF-8 string "\x81\xcc" L v P c, P b - @a - m #7, 3 .5.2 2

Slide 22

Slide 22 text

F x he od L v P c, P b - @a - m #7, 3 .5.2 2

Slide 23

Slide 23 text

func Reverse(s string) string { b := []byte(s) for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 { b[i], b[j] = b[j], b[i] } return string(b) } L v P c, P b - @a - m #7, 3 .5.2 2

Slide 24

Slide 24 text

func Reverse(s string) string { b := []rune(s) for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 { b[i], b[j] = b[j], b[i] } return string(b) } L v P c, P b - @a - m #7, 3 .5.2 2

Slide 25

Slide 25 text

$ go test PASS ok github.com/abtris/golang-meetup-7-fuzz-demo/fuzz 0.098s L v P c, P b - @a - m #7, 3 .5.2 2

Slide 26

Slide 26 text

$ go test -fuzz=Fuzz fuzz: elapsed: 0s, gathering baseline coverage: 0/48 completed fuzz: minimizing 34-byte failing input file fuzz: elapsed: 0s, gathering baseline coverage: 6/48 completed --- FAIL: FuzzReverse (0.03s) --- FAIL: FuzzReverse (0.00s) reverse_test.go:33: Before: "\xe9", after: "�" Failing input written to testdata/fuzz/FuzzReverse/a3cbbeabbd96e2e2c6720a6a50279ffed09b613fd8449f6ce983d151e266243c To re-run: go test -run=FuzzReverse/a3cbbeabbd96e2e2c6720a6a50279ffed09b613fd8449f6ce983d151e266243c FAIL exit status 1 FAIL github.com/abtris/golang-meetup-7-fuzz-demo/fuzz 0.186s L v P c, P b - @a - m #7, 3 .5.2 2

Slide 27

Slide 27 text

F x he od a ai L v P c, P b - @a - m #7, 3 .5.2 2

Slide 28

Slide 28 text

func Reverse(s string) (string, error) { if !utf8.ValidString(s) { return s, errors.New("input is not valid UTF-8") } r := []rune(s) for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { r[i], r[j] = r[j], r[i] } return string(r), nil } L v P c, P b - @a - m #7, 3 .5.2 2

Slide 29

Slide 29 text

$ go test -fuzz=Fuzz -fuzztime 30s fuzz: elapsed: 0s, gathering baseline coverage: 0/72 completed fuzz: elapsed: 0s, gathering baseline coverage: 72/72 completed, now fuzzing with 10 workers fuzz: elapsed: 3s, execs: 1605672 (535192/sec), new interesting: 0 (total: 72) fuzz: elapsed: 6s, execs: 3229185 (541141/sec), new interesting: 0 (total: 72) fuzz: elapsed: 9s, execs: 4764939 (511904/sec), new interesting: 0 (total: 72) fuzz: elapsed: 12s, execs: 6384862 (540026/sec), new interesting: 0 (total: 72) fuzz: elapsed: 15s, execs: 8009255 (541405/sec), new interesting: 0 (total: 72) fuzz: elapsed: 18s, execs: 9605174 (531767/sec), new interesting: 0 (total: 72) fuzz: elapsed: 21s, execs: 11224373 (539649/sec), new interesting: 0 (total: 72) fuzz: elapsed: 24s, execs: 12834356 (536849/sec), new interesting: 0 (total: 72) fuzz: elapsed: 27s, execs: 14441640 (535511/sec), new interesting: 0 (total: 72) fuzz: elapsed: 30s, execs: 16023442 (527570/sec), new interesting: 0 (total: 72) fuzz: elapsed: 30s, execs: 16023442 (0/sec), new interesting: 0 (total: 72) PASS ok github.com/abtris/golang-meetup-7-fuzz-demo 30.346s L v P c, P b - @a - m #7, 3 .5.2 2

Slide 30

Slide 30 text

H w e an un hi i C ? L v P c, P b - @a - m #7, 3 .5.2 3

Slide 31

Slide 31 text

G th b ct on L v P c, P b - @a - m #7, 3 .5.2 3

Slide 32

Slide 32 text

name: Go on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v3 with: go-version-file: "go.mod" - name: Build run: go build -v ./... - name: Test run: go test -v ./... - name: Fuzz test run: go test -v ./... -fuzz=Fuzz -fuzztime 30s L v P c, P b - @a - m #7, 3 .5.2 3

Slide 33

Slide 33 text

G th b ct on 4 u t 4 p l $G O 4 h C 4 c a t L v P c, P b - @a - m #7, 3 .5.2 3

Slide 34

Slide 34 text

F zz uz (b ta) 4 b !!! 4 d e V 4 y a u o n o n (n l n ) L v P c, P b - @a - m #7, 3 .5.2 3

Slide 35

Slide 35 text

L v P c, P b - @a - m #7, 3 .5.2 3

Slide 36

Slide 36 text

L v P c, P b - @a - m #7, 3 .5.2 3

Slide 37

Slide 37 text

L v P c, P b - @a - m #7, 3 .5.2 3

Slide 38

Slide 38 text

L v P c, P b - @a - m #7, 3 .5.2 3

Slide 39

Slide 39 text

F Q L v P c, P b - @a - m #7, 3 .5.2 3

Slide 40

Slide 40 text

R fe en es 4 T A e M E S e D e A e , P e s o A U n C e t (N E !) 4 F T o D e 4 C l f L v P c, P b - @a - m #7, 3 .5.2 4