1
0
mirror of https://github.com/golang/go synced 2024-09-30 04:34:33 -06:00

internal/fuzz: minimize bytes to be human readable

Try to replace every byte with one of the following printable
characters: "012789ABCXYZabcxyz !\"#$%&'()*+,.".

Fixes #48129

Change-Id: Ie58f6bbc3431d50d9f0a3f608ba63e854ac6ce79
Reviewed-on: https://go-review.googlesource.com/c/go/+/352614
Reviewed-by: Katie Hockman <katie@golang.org>
Reviewed-by: Amelia Downs <adowns@vmware.com>
Trust: Katie Hockman <katie@golang.org>
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Amelia Downs 2021-09-27 16:54:39 -04:00 committed by Katie Hockman
parent da7173a2ed
commit c3cb1ecc36
2 changed files with 59 additions and 1 deletions

View File

@ -79,6 +79,25 @@ func minimizeBytes(v []byte, try func(interface{}) bool, shouldStop func() bool)
j = len(v) j = len(v)
} }
} }
// Then, try to make it more simplified and human-readable by trying to replace each
// byte with a printable character.
printableChars := []byte("012789ABCXYZabcxyz !\"#$%&'()*+,.")
for i, b := range v {
if shouldStop() {
return
}
for _, pc := range printableChars {
v[i] = pc
if try(v) {
// Successful. Move on to the next byte in v.
break
}
// Unsuccessful. Revert v[i] back to original value.
v[i] = b
}
}
} }
func minimizeInteger(v uint, try func(interface{}) bool, shouldStop func() bool) { func minimizeInteger(v uint, try func(interface{}) bool, shouldStop func() bool) {

View File

@ -13,6 +13,8 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"testing" "testing"
"unicode"
"unicode/utf8"
) )
func TestMinimizeInput(t *testing.T) { func TestMinimizeInput(t *testing.T) {
@ -54,7 +56,7 @@ func TestMinimizeInput(t *testing.T) {
return fmt.Errorf("bad %v", e.Values[0]) return fmt.Errorf("bad %v", e.Values[0])
}, },
input: []interface{}{[]byte{1, 2, 3, 4, 5}}, input: []interface{}{[]byte{1, 2, 3, 4, 5}},
expected: []interface{}{[]byte{2, 3}}, expected: []interface{}{[]byte("00")},
}, },
{ {
name: "set_of_bytes", name: "set_of_bytes",
@ -71,6 +73,18 @@ func TestMinimizeInput(t *testing.T) {
input: []interface{}{[]byte{0, 1, 2, 3, 4, 5}}, input: []interface{}{[]byte{0, 1, 2, 3, 4, 5}},
expected: []interface{}{[]byte{0, 4, 5}}, expected: []interface{}{[]byte{0, 4, 5}},
}, },
{
name: "non_ascii_bytes",
fn: func(e CorpusEntry) error {
b := e.Values[0].([]byte)
if len(b) == 3 {
return fmt.Errorf("bad %v", e.Values[0])
}
return nil
},
input: []interface{}{[]byte("ท")}, // ท is 3 bytes
expected: []interface{}{[]byte("000")},
},
{ {
name: "ones_string", name: "ones_string",
fn: func(e CorpusEntry) error { fn: func(e CorpusEntry) error {
@ -89,6 +103,31 @@ func TestMinimizeInput(t *testing.T) {
input: []interface{}{"001010001000000000000000000"}, input: []interface{}{"001010001000000000000000000"},
expected: []interface{}{"111"}, expected: []interface{}{"111"},
}, },
{
name: "string_length",
fn: func(e CorpusEntry) error {
b := e.Values[0].(string)
if len(b) == 5 {
return fmt.Errorf("bad %v", e.Values[0])
}
return nil
},
input: []interface{}{"zzzzz"},
expected: []interface{}{"00000"},
},
{
name: "string_with_letter",
fn: func(e CorpusEntry) error {
b := e.Values[0].(string)
r, _ := utf8.DecodeRune([]byte(b))
if unicode.IsLetter(r) {
return fmt.Errorf("bad %v", e.Values[0])
}
return nil
},
input: []interface{}{"ZZZZZ"},
expected: []interface{}{"A"},
},
{ {
name: "int", name: "int",
fn: func(e CorpusEntry) error { fn: func(e CorpusEntry) error {