Files
stun/fuzz_test.go
Joe Turki 0397f2187b Upgrade golangci-lint, more linters
Introduces new linters, upgrade golangci-lint to version (v1.63.4)
2025-01-18 10:57:33 -06:00

157 lines
2.8 KiB
Go

// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
package stun
import (
"encoding/binary"
"errors"
"testing"
)
func FuzzMessage(f *testing.F) {
msg1 := New()
f.Fuzz(func(t *testing.T, data []byte) {
msg1.Reset()
// Fuzzer does not know about cookies
if len(data) >= 8 {
binary.BigEndian.PutUint32(data[4:8], magicCookie)
}
// Trying to read data as message
if _, err := msg1.Write(data); err != nil {
return // We expect invalid messages to fail here
}
msg2 := New()
if _, err := msg2.Write(msg1.Raw); err != nil {
t.Fatalf("Failed to write: %s", err)
}
if msg2.TransactionID != msg1.TransactionID {
t.Fatal("Transaction ID mismatch")
}
if msg2.Type != msg1.Type {
t.Fatal("Type mismatch")
}
if len(msg2.Attributes) != len(msg1.Attributes) {
t.Fatal("Attributes length mismatch")
}
})
}
func FuzzType(f *testing.F) {
f.Fuzz(func(t *testing.T, data uint16) {
v := data & 0x1fff // First 3 bits are empty
t1 := MessageType{}
t1.ReadValue(v)
v2 := t1.Value()
if v != v2 {
t.Fatal("v != v2")
}
t2 := MessageType{}
t2.ReadValue(v2)
if t2 != t1 {
t.Fatal("t2 != t1")
}
})
}
func FuzzSetters(f *testing.F) {
f.Fuzz(func(t *testing.T, firstByte byte, value []byte) {
var (
m1 = &Message{
Raw: make([]byte, 0, 2048),
}
m2 = &Message{
Raw: make([]byte, 0, 2048),
}
m3 = &Message{
Raw: make([]byte, 0, 2048),
}
)
attrs := attributes{
{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},
}
attr := attrs.pick(firstByte)
m1.WriteHeader()
m1.Add(attr.t, value)
err := attr.g.GetFrom(m1)
if errors.Is(err, ErrAttributeNotFound) {
t.Fatalf("Unexpected 404: %s", err)
}
if err != nil {
return
}
m2.WriteHeader()
if err = attr.g.AddTo(m2); err != nil {
// We allow decoding some text attributes
// when their length is too big, but
// not encoding.
if !IsAttrSizeOverflow(err) {
t.Fatal(err)
}
return
}
m3.WriteHeader()
v, err := m2.Get(attr.t)
if err != nil {
t.Fatal(err)
}
m3.Add(attr.t, v)
if !m2.Equal(m3) {
t.Fatalf("Not equal: %s != %s", m2, m3)
}
})
}
func TestAttrPick(*testing.T) {
attrs := attributes{
{new(XORMappedAddress), AttrXORMappedAddress},
}
for i := byte(0); i < 255; i++ {
attrs.pick(i)
}
}
type attr interface {
Getter
Setter
}
type attributes []struct {
g attr
t AttrType
}
func (a attributes) pick(v byte) struct {
g attr
t AttrType
} {
idx := int(v) % len(a)
return a[idx]
}