]> Cypherpunks repositories - gostls13.git/commitdiff
internal/fuzz: minimize bytes to be human readable
authorAmelia Downs <adowns@vmware.com>
Mon, 27 Sep 2021 20:54:39 +0000 (16:54 -0400)
committerKatie Hockman <katie@golang.org>
Tue, 2 Nov 2021 15:51:21 +0000 (15:51 +0000)
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>

src/internal/fuzz/minimize.go
src/internal/fuzz/minimize_test.go

index 974df369eed73d30adc2105cfeb63b701cf67a11..c6e455966508ff91a3ace29c3e34846544448b32 100644 (file)
@@ -79,6 +79,25 @@ func minimizeBytes(v []byte, try func(interface{}) bool, shouldStop func() bool)
                        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) {
index 13385e14d6e35d38f4d4bdc17b8462c72a3de43a..dc153d0de4f0a46d2e685259e539278d1f59c920 100644 (file)
@@ -13,6 +13,8 @@ import (
        "fmt"
        "reflect"
        "testing"
+       "unicode"
+       "unicode/utf8"
 )
 
 func TestMinimizeInput(t *testing.T) {
@@ -54,7 +56,7 @@ func TestMinimizeInput(t *testing.T) {
                                return fmt.Errorf("bad %v", e.Values[0])
                        },
                        input:    []interface{}{[]byte{1, 2, 3, 4, 5}},
-                       expected: []interface{}{[]byte{2, 3}},
+                       expected: []interface{}{[]byte("00")},
                },
                {
                        name: "set_of_bytes",
@@ -71,6 +73,18 @@ func TestMinimizeInput(t *testing.T) {
                        input:    []interface{}{[]byte{0, 1, 2, 3, 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",
                        fn: func(e CorpusEntry) error {
@@ -89,6 +103,31 @@ func TestMinimizeInput(t *testing.T) {
                        input:    []interface{}{"001010001000000000000000000"},
                        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",
                        fn: func(e CorpusEntry) error {