summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/stun/fuzz.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/stun/fuzz.go')
-rw-r--r--vendor/github.com/pion/stun/fuzz.go140
1 files changed, 140 insertions, 0 deletions
diff --git a/vendor/github.com/pion/stun/fuzz.go b/vendor/github.com/pion/stun/fuzz.go
new file mode 100644
index 0000000..debfa8d
--- /dev/null
+++ b/vendor/github.com/pion/stun/fuzz.go
@@ -0,0 +1,140 @@
+// +build gofuzz
+
+package stun
+
+import (
+ "encoding/binary"
+ "fmt"
+)
+
+var (
+ m = New()
+)
+
+// FuzzMessage is go-fuzz endpoint for message.
+func FuzzMessage(data []byte) int {
+ m.Reset()
+ // fuzzer dont know about cookies
+ binary.BigEndian.PutUint32(data[4:8], magicCookie)
+ // trying to read data as message
+ if _, err := m.Write(data); err != nil {
+ return 0
+ }
+ m2 := New()
+ if _, err := m2.Write(m.Raw); err != nil {
+ panic(err) // nolint
+ }
+ if m2.TransactionID != m.TransactionID {
+ panic("transaction ID mismatch") // nolint
+ }
+ if m2.Type != m.Type {
+ panic("type missmatch") // nolint
+ }
+ if len(m2.Attributes) != len(m.Attributes) {
+ panic("attributes length missmatch") // nolint
+ }
+ return 1
+}
+
+// FuzzType is go-fuzz endpoint for message type.
+func FuzzType(data []byte) int {
+ t := MessageType{}
+ vt, _ := binary.Uvarint(data)
+ v := uint16(vt) & 0x1fff // first 3 bits are empty
+ t.ReadValue(v)
+ v2 := t.Value()
+ if v != v2 {
+ panic("v != v2") // nolint
+ }
+ t2 := MessageType{}
+ t2.ReadValue(v2)
+ if t2 != t {
+ panic("t2 != t") // nolint
+ }
+ return 0
+}
+
+type attr interface {
+ Getter
+ Setter
+}
+
+type attrs []struct {
+ g attr
+ t AttrType
+}
+
+func (a attrs) pick(v byte) struct {
+ g attr
+ t AttrType
+} {
+ idx := int(v) % len(a)
+ return a[idx]
+}
+
+func FuzzSetters(data []byte) int {
+ var (
+ m1 = &Message{
+ Raw: make([]byte, 0, 2048),
+ }
+ m2 = &Message{
+ Raw: make([]byte, 0, 2048),
+ }
+ m3 = &Message{
+ Raw: make([]byte, 0, 2048),
+ }
+ )
+ attributes := attrs{
+ {new(Realm), AttrRealm},
+ {new(XORMappedAddress), AttrXORMappedAddress},
+ {new(Nonce), AttrNonce},
+ {new(Software), AttrSoftware},
+ {new(AlternateServer), AttrAlternateServer},
+ {new(ErrorCodeAttribute), AttrErrorCode},
+ {new(UnknownAttributes), AttrUnknownAttributes},
+ {new(Username), AttrUsername},
+ {new(MappedAddress), AttrMappedAddress},
+ {new(Realm), AttrRealm},
+ }
+ var firstByte = byte(0)
+ if len(data) > 0 {
+ firstByte = data[0]
+ }
+ a := attributes.pick(firstByte)
+ value := data
+ if len(data) > 1 {
+ value = value[1:]
+ }
+ m1.WriteHeader()
+ m1.Add(a.t, value)
+ err := a.g.GetFrom(m1)
+ if err == ErrAttributeNotFound {
+ fmt.Println("unexpected 404") // nolint
+ panic(err) // nolint
+ }
+ if err != nil {
+ return 1
+ }
+ m2.WriteHeader()
+ if err = a.g.AddTo(m2); err != nil {
+ // We allow decoding some text attributes
+ // when their length is too big, but
+ // not encoding.
+ if !IsAttrSizeOverflow(err) {
+ panic(err) // nolint
+ }
+ return 1
+ }
+ m3.WriteHeader()
+ v, err := m2.Get(a.t)
+ if err != nil {
+ panic(err) // nolint
+ }
+ m3.Add(a.t, v)
+
+ if !m2.Equal(m3) {
+ fmt.Println(m2, "not equal", m3) // nolint
+ panic("not equal") // nolint
+ }
+ return 1
+}