Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
March 27, 2022 12:00 pm GMT

fuzzing Go

Tutorial Go fuzzing

fuzzing Go random test

input

fuzzing SQL injection, buffer overflow, DoS cross-site scripting

fuzzing

Go Fuzzing glossary

  1. code
  2. unit test
  3. fuzz test

Note: built-in types Go Fuzzing docs

  • Go 1.18
  • Editor
  • command terminal OS
  • fuzznig AMD64 ARM64

  1. command prompt home directory

Linux Mac:

$ cd

Windows:

C:\> cd %HOMEPATH%

$ prompt Windows

  1. command prompt fuzz
$ mkdir fuzz$ cd fuzz
  1. module

go mod init

$ go mod init example/fuzzgo: creating new go.mod: module example/fuzz

code

reverse string

  1. text editor main.go fuzz
  2. main.go package
package main
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)}

string byte string

  1. main
func main() {    input := "The quick brown fox jumped over the lazy dog"    rev := Reverse(input)    doubleRev := Reverse(rev)    fmt.Printf("original: %q
", input) fmt.Printf("reversed: %q
", rev) fmt.Printf("reversed again: %q
", doubleRev)}

command line

  1. main fmt import
package mainimport "fmt"

command line main.go

$ go run .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"

unit test

unit test Reverse

  1. text editor reverse_test.go fuzz
  2. reverse_test.go
package mainimport (    "testing")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)        }    }}

reverse

unit test go test

$ go testPASSok      example/fuzz  0.013s

fuzz test

fuzz test

unit test input developer fuzzing input

unit test fuzz test input

Note: unit test benchmark fuzz *_test.go

text editor reverse_test.go

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)        }    })}

Fuzzing unit test Reverse

Reverse("Hello, world") "dlrow ,olleH"

fuzzing input

fuzz test 2

  1. reverse
  2. reverse UTF-8

Note: unit test fuzz test sysntax :

  • TestXxx FuzzXxx *testing.T *testing.F
  • t.Run f.Fuzz fuzz *testing.T type fuzz input unit test seed corpus f.Add

import unicode/utf8

package mainimport (    "testing"    "unicode/utf8")

fuzz test

  1. fuzz test fuzzing seed
$ go testPASSok      example/fuzz  0.013s

go test -run=FuzzReverse

  1. FuzzReverse fuzzing input flag -fuzz
$ go test -fuzz=Fuzzfuzz: elapsed: 0s, gathering baseline coverage: 0/3 completedfuzz: elapsed: 0s, gathering baseline coverage: 3/3 completed, now fuzzing with 8 workersfuzz: minimizing 38-byte failing input file...--- FAIL: FuzzReverse (0.01s)    --- FAIL: FuzzReverse (0.00s)        reverse_test.go:20: Reverse produced invalid UTF-8 string "\x9c\xdd"    Failing input written to testdata/fuzz/FuzzReverse/af69258a12129d6cbba438df5d5f25ba0ec050461c116f777e77ea7c9a0d217a    To re-run:    go test -run=FuzzReverse/af69258a12129d6cbba438df5d5f25ba0ec050461c116f777e77ea7c9a0d217aFAILexit status 1FAIL    example/fuzz  0.030s

fuzzing input seed corpus go test flag -fuzz input testdata/fuzz/FuzzReverse text editor

go test fuzz v1string("")

type input

  1. go test -fuz seed corpus
$ go test--- FAIL: FuzzReverse (0.00s)    --- FAIL: FuzzReverse/af69258a12129d6cbba438df5d5f25ba0ec050461c116f777e77ea7c9a0d217a (0.00s)        reverse_test.go:20: Reverse produced invalid stringFAILexit status 1FAIL    example/fuzz  0.016s

error

debug

debug VS Code debugger log terminal

utf8.ValidString

ValidString reports whether s consists entirely of valid UTF-8-encoded runes.

Reverse byte byte string UTF-8 rune rune rune

input ( ) Reverse rune

text editor FuzzReverse

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)    }})

t.Logf command line error -v

go test

$ go test--- FAIL: FuzzReverse (0.00s)    --- FAIL: FuzzReverse/28f36ef487f23e6c7a81ebdaa9feffe2f2b02b4cddaa6252e87f69863046a5e0 (0.00s)        reverse_test.go:16: Number of runes: orig=1, rev=3, doubleRev=1        reverse_test.go:21: Reverse produced invalid UTF-8 string "\x83\xb3\xe6"FAILexit status 1FAIL    example/fuzz    0.598s

seed corpus

Error

string runes bytes

text editor Reverse

func Reverse(s string) string {    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)}

Reverse string rune byte

  1. go test
$ go testPASSok      example/fuzz  0.016s

!

  1. Fuzz go test -fuzz
$ go test -fuzz=Fuzzfuzz: elapsed: 0s, gathering baseline coverage: 0/37 completedfuzz: minimizing 506-byte failing input file...fuzz: elapsed: 0s, gathering baseline coverage: 5/37 completed--- FAIL: FuzzReverse (0.02s)    --- FAIL: FuzzReverse (0.00s)        reverse_test.go:33: Before: "\x91", after: ""    Failing input written to testdata/fuzz/FuzzReverse/1ffc28f7538e29d79fce69fef20ce5ea72648529a9ca10bea392bcff28cd015c    To re-run:    go test -run=FuzzReverse/1ffc28f7538e29d79fce69fef20ce5ea72648529a9ca10bea392bcff28cd015cFAILexit status 1FAIL    example/fuzz  0.032s

input unicode ?

debug

debug

debug debugger log

  1. text editor Reverse
func Reverse(s string) string {    fmt.Printf("input: %q
", s) r := []rune(s) fmt.Printf("runes: %q
", r) 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)}

log go test -run

$ go test -run=FuzzReverse/28f36ef487f23e6c7a81ebdaa9feffe2f2b02b4cddaa6252e87f69863046a5e0input: "\x91"runes: ['']input: ""runes: ['']--- FAIL: FuzzReverse (0.00s)    --- FAIL: FuzzReverse/28f36ef487f23e6c7a81ebdaa9feffe2f2b02b4cddaa6252e87f69863046a5e0 (0.00s)        reverse_test.go:16: Number of runes: orig=1, rev=1, doubleRev=1        reverse_test.go:18: Before: "\x91", after: ""FAILexit status 1FAIL    example/fuzz    0.145s

corpus FuzzXxx/testdata {FuzzTestName}/{filename} -run debug

input unicode

error input UTF-8

  1. text editor Reverse
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}

input UTF-8 error

  1. error main
func main() {    input := "The quick brown fox jumped over the lazy dog"    rev, revErr := Reverse(input)    doubleRev, doubleRevErr := Reverse(rev)    fmt.Printf("original: %q
", input) fmt.Printf("reversed: %q, err: %v
", rev, revErr) fmt.Printf("reversed again: %q, err: %v
", doubleRev, doubleRevErr)}

Reverse error nil input UTF-8

  1. import errors unicode/utf8
import (    "errors"    "fmt"    "unicode/utf8")
  1. reverse_test.go error error
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, err1 := Reverse(orig)        if err1 != nil {            return        }        doubleRev, err2 := Reverse(rev)        if err2 != nil {             return        }        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)        }    })}

return t.Skip() input

  1. go test
$ go testPASSok      example/fuzz  0.019s
  1. Fuzz go test -fuzz=Fuzz Ctrl-C
$ go test -fuzz=Fuzzfuzz: elapsed: 0s, gathering baseline coverage: 0/38 completedfuzz: elapsed: 0s, gathering baseline coverage: 38/38 completed, now fuzzing with 4 workersfuzz: elapsed: 3s, execs: 86342 (28778/sec), new interesting: 2 (total: 35)fuzz: elapsed: 6s, execs: 193490 (35714/sec), new interesting: 4 (total: 37)fuzz: elapsed: 9s, execs: 304390 (36961/sec), new interesting: 4 (total: 37)...fuzz: elapsed: 3m45s, execs: 7246222 (32357/sec), new interesting: 8 (total: 41)^Cfuzz: elapsed: 3m48s, execs: 7335316 (31648/sec), new interesting: 8 (total: 41)PASSok      example/fuzz  228.000s

fuzz flag -fuzztime Ctrl-C

  1. Fuzz go test -fuzz=Fuzz -fuzztime 30s fuzz 30
$ go test -fuzz=Fuzz -fuzztime 30sfuzz: elapsed: 0s, gathering baseline coverage: 0/5 completedfuzz: elapsed: 0s, gathering baseline coverage: 5/5 completed, now fuzzing with 4 workersfuzz: elapsed: 3s, execs: 80290 (26763/sec), new interesting: 12 (total: 12)fuzz: elapsed: 6s, execs: 210803 (43501/sec), new interesting: 14 (total: 14)fuzz: elapsed: 9s, execs: 292882 (27360/sec), new interesting: 14 (total: 14)fuzz: elapsed: 12s, execs: 371872 (26329/sec), new interesting: 14 (total: 14)fuzz: elapsed: 15s, execs: 517169 (48433/sec), new interesting: 15 (total: 15)fuzz: elapsed: 18s, execs: 663276 (48699/sec), new interesting: 15 (total: 15)fuzz: elapsed: 21s, execs: 771698 (36143/sec), new interesting: 15 (total: 15)fuzz: elapsed: 24s, execs: 924768 (50990/sec), new interesting: 16 (total: 16)fuzz: elapsed: 27s, execs: 1082025 (52427/sec), new interesting: 17 (total: 17)fuzz: elapsed: 30s, execs: 1172817 (30281/sec), new interesting: 17 (total: 17)fuzz: elapsed: 31s, execs: 1172817 (0/sec), new interesting: 17 (total: 17)PASSok      example/fuzz  31.025s

!

flag -fuzz go test documentation

fuzzing Go

fuzz ! fuzzing trophy case

file and issue

Gpher Slack #fuzzing channel

go.dev/doc/fuzz

main.go

package mainimport (    "errors"    "fmt"    "unicode/utf8")func main() {    input := "The quick brown fox jumped over the lazy dog"    rev, revErr := Reverse(input)    doubleRev, doubleRevErr := Reverse(rev)    fmt.Printf("original: %q
", input) fmt.Printf("reversed: %q, err: %v
", rev, revErr) fmt.Printf("reversed again: %q, err: %v
", doubleRev, doubleRevErr)}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}

reverse_test.go

package mainimport (    "testing"    "unicode/utf8")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, err1 := Reverse(orig)        if err1 != nil {            return        }        doubleRev, err2 := Reverse(rev)        if err2 != nil {            return        }        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)        }    })}

Original Link: https://dev.to/pallat/eriiynruueruueng-fuzzing-ain-go-2jh5

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To