mirror of
https://github.com/golang/go
synced 2024-11-24 01:30:10 -07:00
internal/fuzz: allocate memory for mutated strings
Rather than directly pointing at the underlying scratch slice, allocate memory for strings. This prevents mutation of previous values we've passed to the fuzz function, which may be retained by something that expects them to be immutable. Fixes golang/go#48308 Change-Id: Iee9bed1a536fdc4188180e8e7c1c722f641271d2 Reviewed-on: https://go-review.googlesource.com/c/go/+/351312 Trust: Roland Shoemaker <roland@golang.org> Trust: Katie Hockman <katie@golang.org> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com> Reviewed-by: Katie Hockman <katie@golang.org>
This commit is contained in:
parent
91c2318e67
commit
ccf140f3d7
@ -106,12 +106,7 @@ func (m *mutator) mutate(vals []interface{}, maxBytes int) {
|
||||
copy(m.scratch, v)
|
||||
}
|
||||
m.mutateBytes(&m.scratch)
|
||||
var s string
|
||||
shdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||
bhdr := (*reflect.SliceHeader)(unsafe.Pointer(&m.scratch))
|
||||
shdr.Data = bhdr.Data
|
||||
shdr.Len = bhdr.Len
|
||||
vals[i] = s
|
||||
vals[i] = string(m.scratch)
|
||||
case []byte:
|
||||
if len(v) > maxPerVal {
|
||||
panic(fmt.Sprintf("cannot mutate bytes of length %d", len(v)))
|
||||
|
@ -5,6 +5,7 @@
|
||||
package fuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
@ -99,3 +100,18 @@ func BenchmarkMutatorAllBasicTypes(b *testing.B) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringImmutability(t *testing.T) {
|
||||
v := []interface{}{"hello"}
|
||||
m := newMutator()
|
||||
m.mutate(v, 1024)
|
||||
original := v[0].(string)
|
||||
originalCopy := make([]byte, len(original))
|
||||
copy(originalCopy, []byte(original))
|
||||
for i := 0; i < 25; i++ {
|
||||
m.mutate(v, 1024)
|
||||
}
|
||||
if !bytes.Equal([]byte(original), originalCopy) {
|
||||
t.Fatalf("string was mutated: got %x, want %x", []byte(original), originalCopy)
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +293,10 @@ var supportedTypes = map[reflect.Type]bool{
|
||||
// f.Fuzz(func(t *testing.T, b []byte, i int) { ... })
|
||||
//
|
||||
// This function should be fast, deterministic, and stateless.
|
||||
// None of the pointers to any input data should be retained between executions.
|
||||
//
|
||||
// No mutatable input arguments, or pointers to them, should be retained between
|
||||
// executions of the fuzz function, as the memory backing them may be mutated
|
||||
// during a subsequent invocation.
|
||||
//
|
||||
// This is a terminal function which will terminate the currently running fuzz
|
||||
// target by calling runtime.Goexit.
|
||||
|
Loading…
Reference in New Issue
Block a user