Skip to content
This repository has been archived by the owner on Jun 5, 2021. It is now read-only.

Commit

Permalink
attrs: add CheckOverflow and IsAttrSizeOverflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ernado committed Aug 2, 2018
1 parent b591245 commit 872811a
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 92 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,6 @@ test-integration:
@cd e2e && bash ./test.sh
prepush: test lint test-integration
check-api:
@api -c api/stun1.txt,api/stun1.12.txt github.com/gortc/stun
@api -c api/stun1.txt github.com/gortc/stun
write-api:
@api github.com/gortc/stun > api/stun1.txt
1 change: 0 additions & 1 deletion api/stun1.12.txt

This file was deleted.

15 changes: 5 additions & 10 deletions api/stun1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,13 @@ pkg github.com/gortc/stun, const MethodSend Method
pkg github.com/gortc/stun, const TransactionIDSize = 12
pkg github.com/gortc/stun, const TransactionIDSize ideal-int
pkg github.com/gortc/stun, func Build(...Setter) (*Message, error)
pkg github.com/gortc/stun, func CheckOverflow(AttrType, int, int) error
pkg github.com/gortc/stun, func CheckSize(AttrType, int, int) error
pkg github.com/gortc/stun, func Decode([]uint8, *Message) error
pkg github.com/gortc/stun, func Dial(string, string) (*Client, error)
pkg github.com/gortc/stun, func FingerprintValue([]uint8) uint32
pkg github.com/gortc/stun, func IsAttrSizeInvalid(error) bool
pkg github.com/gortc/stun, func IsAttrSizeOverflow(error) bool
pkg github.com/gortc/stun, func IsMessage([]uint8) bool
pkg github.com/gortc/stun, func MustBuild(...Setter) *Message
pkg github.com/gortc/stun, func New() *Message
Expand Down Expand Up @@ -146,6 +148,7 @@ pkg github.com/gortc/stun, method (*Message) Contains(AttrType) bool
pkg github.com/gortc/stun, method (*Message) Decode() error
pkg github.com/gortc/stun, method (*Message) Encode()
pkg github.com/gortc/stun, method (*Message) Equal(*Message) bool
pkg github.com/gortc/stun, method (*Message) ForEach(AttrType, func(*Message) error) error
pkg github.com/gortc/stun, method (*Message) Get(AttrType) ([]uint8, error)
pkg github.com/gortc/stun, method (*Message) NewTransactionID() error
pkg github.com/gortc/stun, method (*Message) Parse(...Getter) error
Expand All @@ -169,8 +172,6 @@ pkg github.com/gortc/stun, method (*UnknownAttributes) GetFrom(*Message) error
pkg github.com/gortc/stun, method (*Username) GetFrom(*Message) error
pkg github.com/gortc/stun, method (*XORMappedAddress) GetFrom(*Message) error
pkg github.com/gortc/stun, method (*XORMappedAddress) GetFromAs(*Message, AttrType) error
pkg github.com/gortc/stun, method (AttrLengthErr) Error() string
pkg github.com/gortc/stun, method (AttrOverflowErr) Error() string
pkg github.com/gortc/stun, method (AttrType) Optional() bool
pkg github.com/gortc/stun, method (AttrType) Required() bool
pkg github.com/gortc/stun, method (AttrType) String() string
Expand Down Expand Up @@ -221,14 +222,6 @@ pkg github.com/gortc/stun, type AgentOptions struct, Handler Handler
pkg github.com/gortc/stun, type AlternateServer struct
pkg github.com/gortc/stun, type AlternateServer struct, IP net.IP
pkg github.com/gortc/stun, type AlternateServer struct, Port int
pkg github.com/gortc/stun, type AttrLengthErr struct
pkg github.com/gortc/stun, type AttrLengthErr struct, Attr AttrType
pkg github.com/gortc/stun, type AttrLengthErr struct, Expected int
pkg github.com/gortc/stun, type AttrLengthErr struct, Got int
pkg github.com/gortc/stun, type AttrOverflowErr struct
pkg github.com/gortc/stun, type AttrOverflowErr struct, Got int
pkg github.com/gortc/stun, type AttrOverflowErr struct, Max int
pkg github.com/gortc/stun, type AttrOverflowErr struct, Type AttrType
pkg github.com/gortc/stun, type AttrType uint16
pkg github.com/gortc/stun, type Attributes []RawAttribute
pkg github.com/gortc/stun, type Checker interface { Check }
Expand Down Expand Up @@ -309,6 +302,8 @@ pkg github.com/gortc/stun, var BindingSuccess MessageType
pkg github.com/gortc/stun, var ErrAgentClosed error
pkg github.com/gortc/stun, var ErrAttrSizeInvalid error
pkg github.com/gortc/stun, var ErrAttributeNotFound error
pkg github.com/gortc/stun, var ErrAttributeSizeInvalid error
pkg github.com/gortc/stun, var ErrAttributeSizeOverflow error
pkg github.com/gortc/stun, var ErrBadIPLength error
pkg github.com/gortc/stun, var ErrBadUnknownAttrsSize error
pkg github.com/gortc/stun, var ErrClientClosed error
Expand Down
28 changes: 0 additions & 28 deletions attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,34 +172,6 @@ func (m *Message) Get(t AttrType) ([]byte, error) {
return v.Value, nil
}

// AttrOverflowErr occurs when len(v) > Max.
type AttrOverflowErr struct {
Type AttrType
Max int
Got int
}

func (e AttrOverflowErr) Error() string {
return fmt.Sprintf("incorrect length of %s attribute: %d exceeds maximum %d",
e.Type, e.Got, e.Max,
)
}

// AttrLengthErr means that length for attribute is invalid.
type AttrLengthErr struct {
Attr AttrType
Got int
Expected int
}

func (e AttrLengthErr) Error() string {
return fmt.Sprintf("incorrect length of %s attribute: got %d, expected %d",
e.Attr,
e.Got,
e.Expected,
)
}

// STUN aligns attributes on 32-bit boundaries, attributes whose content
// is not a multiple of 4 bytes are padded with 1, 2, or 3 bytes of
// padding so that its value contains a multiple of 4 bytes. The
Expand Down
33 changes: 33 additions & 0 deletions attributes_debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// +build debug

package stun

import "fmt"

// AttrOverflowErr occurs when len(v) > Max.
type AttrOverflowErr struct {
Type AttrType
Max int
Got int
}

func (e AttrOverflowErr) Error() string {
return fmt.Sprintf("incorrect length of %s attribute: %d exceeds maximum %d",
e.Type, e.Got, e.Max,
)
}

// AttrLengthErr means that length for attribute is invalid.
type AttrLengthErr struct {
Attr AttrType
Got int
Expected int
}

func (e AttrLengthErr) Error() string {
return fmt.Sprintf("incorrect length of %s attribute: got %d, expected %d",
e.Attr,
e.Got,
e.Expected,
)
}
27 changes: 27 additions & 0 deletions attributes_debug_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// +build debug

package stun

import "testing"

func TestAttrOverflowErr_Error(t *testing.T) {
err := AttrOverflowErr{
Got: 100,
Max: 50,
Type: AttrLifetime,
}
if err.Error() != "incorrect length of LIFETIME attribute: 100 exceeds maximum 50" {
t.Error("bad error string", err)
}
}

func TestAttrLengthErr_Error(t *testing.T) {
err := AttrLengthErr{
Attr: AttrErrorCode,
Expected: 15,
Got: 99,
}
if err.Error() != "incorrect length of ERROR-CODE attribute: got 99, expected 15" {
t.Errorf("bad error string: %s", err)
}
}
22 changes: 0 additions & 22 deletions attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,28 +69,6 @@ func TestPadding(t *testing.T) {
}
}

func TestAttrLengthError_Error(t *testing.T) {
err := AttrOverflowErr{
Got: 100,
Max: 50,
Type: AttrLifetime,
}
if err.Error() != "incorrect length of LIFETIME attribute: 100 exceeds maximum 50" {
t.Error("bad error string", err)
}
}

func TestAttrLengthErr_Error(t *testing.T) {
err := AttrLengthErr{
Attr: AttrErrorCode,
Expected: 15,
Got: 99,
}
if err.Error() != "incorrect length of ERROR-CODE attribute: got 99, expected 15" {
t.Errorf("bad error string: %s", err)
}
}

func TestAttrTypeRange(t *testing.T) {
for _, a := range []AttrType{
AttrPriority,
Expand Down
17 changes: 15 additions & 2 deletions checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func CheckSize(_ AttrType, got, expected int) error {
if got == expected {
return nil
}
return ErrAttrSizeInvalid
return ErrAttributeSizeInvalid
}

func checkHMAC(got, expected []byte) error {
Expand All @@ -28,5 +28,18 @@ func checkFingerprint(got, expected uint32) error {

// IsAttrSizeInvalid returns true if error means that attribute size is invalid.
func IsAttrSizeInvalid(err error) bool {
return err == ErrAttrSizeInvalid
return err == ErrAttributeSizeInvalid
}

// CheckOverflow returns ErrAttributeSizeOverflow if got is bigger that max.
func CheckOverflow(_ AttrType, got, max int) error {
if got <= max {
return nil
}
return ErrAttributeSizeOverflow
}

// IsAttrSizeOverflow returns true if error means that attribute size is too big.
func IsAttrSizeOverflow(err error) bool {
return err == ErrAttributeSizeOverflow
}
18 changes: 18 additions & 0 deletions checks_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,21 @@ func IsAttrSizeInvalid(err error) bool {
_, ok := err.(*AttrLengthErr)
return ok
}

// CheckOverflow returns *AttrOverflowErr if got is bigger that max.
func CheckOverflow(t AttrType, got, max int) error {
if got <= max {
return nil
}
return &AttrOverflowErr{
Type: t,
Got: got,
Max: max,
}
}

// IsAttrSizeOverflow returns true if error means that attribute size is too big.
func IsAttrSizeOverflow(err error) bool {
_, ok := err.(*AttrOverflowErr)
return ok
}
11 changes: 5 additions & 6 deletions errorcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ const (
// AddTo adds ERROR-CODE to m.
func (c ErrorCodeAttribute) AddTo(m *Message) error {
value := make([]byte, 0, errorCodeReasonMaxB)
if len(c.Reason) > errorCodeReasonMaxB {
return &AttrOverflowErr{
Got: len(c.Reason) + errorCodeReasonStart,
Max: errorCodeReasonMaxB + errorCodeReasonStart,
Type: AttrErrorCode,
}
if err := CheckOverflow(AttrErrorCode,
len(c.Reason)+errorCodeReasonStart,
errorCodeReasonMaxB+errorCodeReasonStart,
); err != nil {
return err
}
value = value[:errorCodeReasonStart+len(c.Reason)]
number := byte(c.Code % errorCodeModulo) // error code modulo 100
Expand Down
8 changes: 8 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,12 @@ func newAttrDecodeErr(children, message string) *DecodeErr {
}

// ErrAttrSizeInvalid means that decoded attribute size is invalid.
//
// DEPRECATED: use ErrAttributeSizeInvalid.
var ErrAttrSizeInvalid = errors.New("attribute size is invalid")

// ErrAttributeSizeInvalid means that decoded attribute size is invalid.
var ErrAttributeSizeInvalid = ErrAttrSizeInvalid

// ErrAttributeSizeOverflow means that decoded attribute size is too big.
var ErrAttributeSizeOverflow = errors.New("attribute size overflow")
8 changes: 2 additions & 6 deletions textattrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,8 @@ type TextAttribute []byte
// AddToAs adds attribute with type t to m, checking maximum length. If maxLen
// is less than 0, no check is performed.
func (v TextAttribute) AddToAs(m *Message, t AttrType, maxLen int) error {
if maxLen > 0 && len(v) > maxLen {
return &AttrOverflowErr{
Max: maxLen,
Got: len(v),
Type: t,
}
if err := CheckOverflow(t, len(v), maxLen); err != nil {
return err
}
m.Add(t, v)
return nil
Expand Down
10 changes: 5 additions & 5 deletions textattrs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestSoftware_GetFrom(t *testing.T) {
func TestSoftware_AddTo_Invalid(t *testing.T) {
m := New()
s := make(Software, 1024)
if err, ok := s.AddTo(m).(*AttrOverflowErr); !ok {
if err := s.AddTo(m); !IsAttrSizeOverflow(err) {
t.Errorf("AddTo should return *AttrOverflowErr, got: %v", err)
}
if err := s.GetFrom(m); err != ErrAttributeNotFound {
Expand Down Expand Up @@ -88,8 +88,8 @@ func TestUsername(t *testing.T) {
m.WriteHeader()
t.Run("Bad length", func(t *testing.T) {
badU := make(Username, 600)
if err, ok := badU.AddTo(m).(*AttrOverflowErr); !ok {
t.Errorf("expected length error, got %v", err)
if err := badU.AddTo(m); !IsAttrSizeOverflow(err) {
t.Errorf("AddTo should return *AttrOverflowErr, got: %v", err)
}
})
t.Run("AddTo", func(t *testing.T) {
Expand Down Expand Up @@ -164,7 +164,7 @@ func TestRealm_GetFrom(t *testing.T) {
func TestRealm_AddTo_Invalid(t *testing.T) {
m := New()
r := make(Realm, 1024)
if err, ok := r.AddTo(m).(*AttrOverflowErr); !ok || err.Type != AttrRealm {
if err := r.AddTo(m); !IsAttrSizeOverflow(err) {
t.Errorf("AddTo should return *AttrOverflowErr, got: %v", err)
}
if err := r.GetFrom(m); err != ErrAttributeNotFound {
Expand Down Expand Up @@ -205,7 +205,7 @@ func TestNonce_GetFrom(t *testing.T) {
func TestNonce_AddTo_Invalid(t *testing.T) {
m := New()
n := make(Nonce, 1024)
if err, ok := n.AddTo(m).(*AttrOverflowErr); !ok || err.Type != AttrNonce {
if err := n.AddTo(m); !IsAttrSizeOverflow(err) {
t.Errorf("AddTo should return *AttrOverflowErr, got: %v", err)
}
if err := n.GetFrom(m); err != ErrAttributeNotFound {
Expand Down
8 changes: 2 additions & 6 deletions xoraddr.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,8 @@ func (a *XORMappedAddress) GetFromAs(m *Message, t AttrType) error {
if len(v) <= 4 {
return io.ErrUnexpectedEOF
}
if len(v[4:]) > len(a.IP) {
return &AttrOverflowErr{
Got: len(v[4:]),
Type: AttrXORMappedAddress,
Max: len(a.IP),
}
if err := CheckOverflow(t, len(v[4:]), len(a.IP)); err != nil {
return err
}
a.Port = int(bin.Uint16(v[2:4])) ^ (magicCookie >> 16)
xorValue := make([]byte, 4+TransactionIDSize)
Expand Down
7 changes: 2 additions & 5 deletions xoraddr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,8 @@ func TestXORMappedAddress_GetFrom(t *testing.T) {
// {0, 1} is correct addr family.
m.Add(AttrXORMappedAddress, []byte{0, 1, 3, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 2, 3, 4})
addr := new(XORMappedAddress)
err := addr.GetFrom(m)
if _, ok := err.(*AttrOverflowErr); !ok {
t.Errorf("should render AttrOverflowErr error, got <%s> (%T)",
err, err,
)
if err := addr.GetFrom(m); !IsAttrSizeOverflow(err) {
t.Errorf("AddTo should return *AttrOverflowErr, got: %v", err)
}
})
}
Expand Down

0 comments on commit 872811a

Please sign in to comment.