File: fuzz.go

package info (click to toggle)
golang-github-bradenaw-juniper 0.15.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 872 kB
  • sloc: sh: 27; makefile: 2
file content (97 lines) | stat: -rw-r--r-- 1,658 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package fuzz

import (
	"encoding/binary"
	"fmt"
	"reflect"
)

func Operations(b []byte, check func(), fns ...interface{}) {
	choose := func(n int) (int, bool) {
		if len(b) < 1 {
			return 0, false
		}
		if n > 255 {
			panic("")
		}
		choice := int(b[0])
		if choice >= n {
			return 0, false
		}
		b = b[1:]
		return choice, true
	}
	takeByte := func() (byte, bool) {
		if len(b) < 1 {
			return 0, false
		}
		x := b[0]
		b = b[1:]
		return x, true
	}
	takeUint16 := func() (uint16, bool) {
		if len(b) < 2 {
			return 0, false
		}
		x := uint16(binary.BigEndian.Uint16(b[:2]))
		b = b[2:]
		return x, true
	}
	takeInt := func() (int, bool) {
		if len(b) < 8 {
			return 0, false
		}
		x := int(binary.BigEndian.Uint64(b[:8]))
		b = b[8:]
		return x, true
	}
	takeBool := func() (bool, bool) {
		b, ok := takeByte()
		return b != 0, ok
	}

Loop:
	for {
		check()
		i, ok := choose(len(fns))
		if !ok {
			break
		}
		fnV := reflect.ValueOf(fns[i])

		args := make([]reflect.Value, fnV.Type().NumIn())
		for j := range args {
			argType := fnV.Type().In(j)

			switch argType.Kind() {
			case reflect.Int:
				x, ok := takeInt()
				if !ok {
					break Loop
				}
				args[j] = reflect.ValueOf(x)
			case reflect.Uint8:
				x, ok := takeByte()
				if !ok {
					break Loop
				}
				args[j] = reflect.ValueOf(x)
			case reflect.Uint16:
				x, ok := takeUint16()
				if !ok {
					break Loop
				}
				args[j] = reflect.ValueOf(x)
			case reflect.Bool:
				x, ok := takeBool()
				if !ok {
					break Loop
				}
				args[j] = reflect.ValueOf(x)
			default:
				panic(fmt.Sprintf("arg type %s not supported", argType.Kind()))
			}
		}
		fnV.Call(args)
	}
}