aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-12-08 10:22:56 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-12-08 10:22:56 +0100
commitc29495e0f971d3dbe7dbfe2db3c65f056efe9f3c (patch)
treebe3ed8510cdbb64731028b59969adc05d0feb8d0
parentc0e5b8c81f054a301aeaaa16bf9c6220ba73d833 (diff)
prog: append a bunch of bytes during mutation
In some cases we need to extend a buffer by a large margin to pass the next if in kernel (a size check). Currently we only append a single byte, so we can never pass the if incrementally (size is always smaller than threshold, so 1-byte larger inputs are not added to corpus).
-rw-r--r--prog/mutation.go26
1 files changed, 20 insertions, 6 deletions
diff --git a/prog/mutation.go b/prog/mutation.go
index 920888c2b..63c58ad7f 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -9,6 +9,8 @@ import (
"unsafe"
)
+const maxBlobLen = uint64(100 << 10)
+
func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Prog) {
r := newRand(p.Target, rs)
@@ -101,16 +103,14 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Pro
case BufferBlobRand, BufferBlobRange:
var data []byte
data = append([]byte{}, a.Data...)
- var minLen uint64
- maxLen := ^uint64(0)
+ minLen, maxLen := uint64(0), maxBlobLen
if t.Kind == BufferBlobRange {
- minLen = t.RangeBegin
- maxLen = t.RangeEnd
+ minLen, maxLen = t.RangeBegin, t.RangeEnd
}
a.Data = mutateData(r, data, minLen, maxLen)
case BufferString:
if r.bin() {
- minLen, maxLen := uint64(0), ^uint64(0)
+ minLen, maxLen := uint64(0), maxBlobLen
if t.TypeSize != 0 {
minLen, maxLen = t.TypeSize, t.TypeSize
}
@@ -592,7 +592,7 @@ func mutateData(r *randGen, data []byte, minLen, maxLen uint64) []byte {
loop:
for stop := false; !stop || retry; stop = r.oneOf(3) {
retry = false
- switch r.Intn(13) {
+ switch r.Intn(14) {
case 0:
// Append byte.
if uint64(len(data)) >= maxLen {
@@ -740,6 +740,20 @@ loop:
value = swap64(value)
}
*(*uint64)(unsafe.Pointer(&data[i])) = value
+ case 13:
+ // Append a bunch of bytes.
+ if uint64(len(data)) >= maxLen {
+ retry = true
+ continue loop
+ }
+ const max = 256
+ n := max - r.biasedRand(max, 10)
+ if r := int(maxLen) - len(data); n > r {
+ n = r
+ }
+ for i := 0; i < n; i++ {
+ data = append(data, byte(r.rand(256)))
+ }
default:
panic("bad")
}