d. 在main.go的顶部,在包声明的下面,粘贴以下main函数,以初始化一个字符串,反转它,打印输出,然后重复。
1
2
3
4
5
6
7
8
funcmain(){input:="The quick brown fox jumped over the lazy dog"rev:=Reverse(input)doubleRev:=Reverse(rev)fmt.Printf("original: %q\n",input)fmt.Printf("reversed: %q\n",rev)fmt.Printf("reversed again: %q\n",doubleRev)}
$ 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"
funcFuzzReverse(f*testing.F){testcases:=[]string{"Hello, world"," ","!12345"}for_,tc:=rangetestcases{f.Add(tc)// Use f.Add to provide a seed corpus
}f.Fuzz(func(t*testing.T,origstring){rev:=Reverse(orig)doubleRev:=Reverse(rev)iforig!=doubleRev{t.Errorf("Before: %q, after: %q",orig,doubleRev)}ifutf8.ValidString(orig)&&!utf8.ValidString(rev){t.Errorf("Reverse produced invalid UTF-8 string %q",rev)}})}
funcReverse(sstring)(string,error){if!utf8.ValidString(s){returns,errors.New("input is not valid UTF-8")}r:=[]rune(s)fori,j:=0,len(r)-1;i<len(r)/2;i,j=i+1,j-1{r[i],r[j]=r[j],r[i]}returnstring(r),nil}
如果输入的字符串包含无效的UTF-8字符,这一改变将返回一个错误。
b. 由于Reverse函数现在返回一个错误,请修改main函数以丢弃额外的错误值。将现有的main函数改为以下内容。
1
2
3
4
5
6
7
8
funcmain(){input:="The quick brown fox jumped over the lazy dog"rev,revErr:=Reverse(input)doubleRev,doubleRevErr:=Reverse(rev)fmt.Printf("original: %q\n",input)fmt.Printf("reversed: %q, err: %v\n",rev,revErr)fmt.Printf("reversed again: %q, err: %v\n",doubleRev,doubleRevErr)}
这些对Reverse的调用应该返回一个nil错误,当输入的字符串是有效的UTF-8。
c. 您将需要导入错误和unicode/utf8包。main.go中的import语句应该如下所示。
funcFuzzReverse(f*testing.F){testcases:=[]string{"Hello, world"," ","!12345"}for_,tc:=rangetestcases{f.Add(tc)// Use f.Add to provide a seed corpus
}f.Fuzz(func(t*testing.T,origstring){rev,err1:=Reverse(orig)iferr1!=nil{return}doubleRev,err2:=Reverse(rev)iferr2!=nil{return}iforig!=doubleRev{t.Errorf("Before: %q, after: %q",orig,doubleRev)}ifutf8.ValidString(orig)&&!utf8.ValidString(rev){t.Errorf("Reverse produced invalid UTF-8 string %q",rev)}})}
您也可以调用t.Skip()而不是返回,以停止执行该模糊输入。
运行代码
a. 使用go test运行测试
1
2
3
$ go testPASS
ok example/fuzz 0.019s
b. Fuzz it with go test -fuzz=Fuzz, then after a few seconds has passed, stop fuzzing with ctrl-C. 用go test -fuzz=Fuzz进行模糊测试,然后在几秒钟后,用ctrl-C停止模糊测试。
1
2
3
4
5
6
7
8
9
10
11
$ go test -fuzz=Fuzz
fuzz: elapsed: 0s, gathering baseline coverage: 0/38 completed
fuzz: elapsed: 0s, gathering baseline coverage: 38/38 completed, now fuzzing with 4 workers
fuzz: 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)PASS
ok example/fuzz 228.000s
packagemainimport("errors""fmt""unicode/utf8")funcmain(){input:="The quick brown fox jumped over the lazy dog"rev,revErr:=Reverse(input)doubleRev,doubleRevErr:=Reverse(rev)fmt.Printf("original: %q\n",input)fmt.Printf("reversed: %q, err: %v\n",rev,revErr)fmt.Printf("reversed again: %q, err: %v\n",doubleRev,doubleRevErr)}funcReverse(sstring)(string,error){if!utf8.ValidString(s){returns,errors.New("input is not valid UTF-8")}r:=[]rune(s)fori,j:=0,len(r)-1;i<len(r)/2;i,j=i+1,j-1{r[i],r[j]=r[j],r[i]}returnstring(r),nil}
packagemainimport("testing""unicode/utf8")funcFuzzReverse(f*testing.F){testcases:=[]string{"Hello, world"," ","!12345"}for_,tc:=rangetestcases{f.Add(tc)// Use f.Add to provide a seed corpus
}f.Fuzz(func(t*testing.T,origstring){rev,err1:=Reverse(orig)iferr1!=nil{return}doubleRev,err2:=Reverse(rev)iferr2!=nil{return}iforig!=doubleRev{t.Errorf("Before: %q, after: %q",orig,doubleRev)}ifutf8.ValidString(orig)&&!utf8.ValidString(rev){t.Errorf("Reverse produced invalid UTF-8 string %q",rev)}})}