Move encoding artifacts to internal/encoding package (#60)

This required exporting of the marshal and unmarshal methods.
Exported the bare minimum things from the encoding package.
Moved Error and ErrorCondition to this package as it's needed at this
low level.
Split fuzz testing into two separate tests depending on scope.
Moved test assets under testdata directory per convention.
This commit is contained in:
Joel Hendrix 2021-09-09 10:24:27 -07:00 коммит произвёл GitHub
Родитель 5f90521fe1
Коммит 76dfabb04f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
589 изменённых файлов: 1465 добавлений и 1349 удалений

Просмотреть файл

@ -11,6 +11,8 @@ import (
"net/url"
"sync"
"time"
"github.com/Azure/go-amqp/internal/encoding"
)
var (
@ -305,9 +307,9 @@ func linkProperty(key string, value interface{}) LinkOption {
return errors.New("link property key must not be empty")
}
if l.properties == nil {
l.properties = make(map[symbol]interface{})
l.properties = make(map[encoding.Symbol]interface{})
}
l.properties[symbol(key)] = value
l.properties[encoding.Symbol(key)] = value
return nil
}
}
@ -332,9 +334,9 @@ func LinkSourceCapabilities(capabilities ...string) LinkOption {
}
// Convert string to symbol
symbolCapabilities := make([]symbol, len(capabilities))
symbolCapabilities := make([]encoding.Symbol, len(capabilities))
for i, v := range capabilities {
symbolCapabilities[i] = symbol(v)
symbolCapabilities[i] = encoding.Symbol(v)
}
l.source.Capabilities = append(l.source.Capabilities, symbolCapabilities...)
@ -488,19 +490,19 @@ func LinkSourceFilter(name string, code uint64, value interface{}) LinkOption {
l.source = new(source)
}
if l.source.Filter == nil {
l.source.Filter = make(map[symbol]*describedType)
l.source.Filter = make(map[encoding.Symbol]*encoding.DescribedType)
}
var descriptor interface{}
if code != 0 {
descriptor = code
} else {
descriptor = symbol(name)
descriptor = encoding.Symbol(name)
}
l.source.Filter[symbol(name)] = &describedType{
descriptor: descriptor,
value: value,
l.source.Filter[encoding.Symbol(name)] = &encoding.DescribedType{
Descriptor: descriptor,
Value: value,
}
return nil
}

Просмотреть файл

@ -3,6 +3,8 @@ package amqp
import (
"encoding/binary"
"testing"
"github.com/Azure/go-amqp/internal/encoding"
)
func TestLinkOptions(t *testing.T) {
@ -11,7 +13,7 @@ func TestLinkOptions(t *testing.T) {
opts []LinkOption
wantSource *source
wantProperties map[symbol]interface{}
wantProperties map[encoding.Symbol]interface{}
}{
{
label: "no options",
@ -29,18 +31,18 @@ func TestLinkOptions(t *testing.T) {
},
wantSource: &source{
Filter: map[symbol]*describedType{
Filter: map[encoding.Symbol]*encoding.DescribedType{
"apache.org:selector-filter:string": {
descriptor: binary.BigEndian.Uint64([]byte{0x00, 0x00, 0x46, 0x8C, 0x00, 0x00, 0x00, 0x04}),
value: "amqp.annotation.x-opt-offset > '100'",
Descriptor: binary.BigEndian.Uint64([]byte{0x00, 0x00, 0x46, 0x8C, 0x00, 0x00, 0x00, 0x04}),
Value: "amqp.annotation.x-opt-offset > '100'",
},
"com.microsoft:session-filter": {
descriptor: binary.BigEndian.Uint64([]byte{0x00, 0x00, 0x00, 0x13, 0x70, 0x00, 0x00, 0x0C}),
value: "123",
Descriptor: binary.BigEndian.Uint64([]byte{0x00, 0x00, 0x00, 0x13, 0x70, 0x00, 0x00, 0x0C}),
Value: "123",
},
},
},
wantProperties: map[symbol]interface{}{
wantProperties: map[encoding.Symbol]interface{}{
"x-opt-test1": "test3",
"x-opt-test2": "test2",
"x-opt-test4": int64(1),
@ -54,10 +56,10 @@ func TestLinkOptions(t *testing.T) {
},
wantSource: &source{
Filter: map[symbol]*describedType{
Filter: map[encoding.Symbol]*encoding.DescribedType{
"com.microsoft:session-filter": {
descriptor: binary.BigEndian.Uint64([]byte{0x00, 0x00, 0x00, 0x13, 0x70, 0x00, 0x00, 0x0C}),
value: nil,
Descriptor: binary.BigEndian.Uint64([]byte{0x00, 0x00, 0x00, 0x13, 0x70, 0x00, 0x00, 0x0C}),
Value: nil,
},
},
},
@ -68,7 +70,7 @@ func TestLinkOptions(t *testing.T) {
LinkSourceCapabilities("cap1", "cap2", "cap3"),
},
wantSource: &source{
Capabilities: []symbol{"cap1", "cap2", "cap3"},
Capabilities: []encoding.Symbol{"cap1", "cap2", "cap3"},
},
},
}

75
conn.go
Просмотреть файл

@ -13,6 +13,7 @@ import (
"time"
"github.com/Azure/go-amqp/internal/buffer"
"github.com/Azure/go-amqp/internal/encoding"
)
// Default connection options
@ -145,9 +146,9 @@ func ConnProperty(key, value string) ConnOption {
return errors.New("connection property key must not be empty")
}
if c.properties == nil {
c.properties = make(map[symbol]interface{})
c.properties = make(map[encoding.Symbol]interface{})
}
c.properties[symbol(key)] = value
c.properties[encoding.Symbol(key)] = value
return nil
}
}
@ -173,16 +174,16 @@ type conn struct {
tlsConfig *tls.Config // TLS config, default used if nil (ServerName set to Client.hostname)
// SASL
saslHandlers map[symbol]stateFunc // map of supported handlers keyed by SASL mechanism, SASL not negotiated if nil
saslComplete bool // SASL negotiation complete
saslHandlers map[encoding.Symbol]stateFunc // map of supported handlers keyed by SASL mechanism, SASL not negotiated if nil
saslComplete bool // SASL negotiation complete
// local settings
maxFrameSize uint32 // max frame size to accept
channelMax uint16 // maximum number of channels to allow
hostname string // hostname of remote server (set explicitly or parsed from URL)
idleTimeout time.Duration // maximum period between receiving frames
properties map[symbol]interface{} // additional properties sent upon connection open
containerID string // set explicitly or randomly generated
maxFrameSize uint32 // max frame size to accept
channelMax uint16 // maximum number of channels to allow
hostname string // hostname of remote server (set explicitly or parsed from URL)
idleTimeout time.Duration // maximum period between receiving frames
properties map[encoding.Symbol]interface{} // additional properties sent upon connection open
containerID string // set explicitly or randomly generated
// peer settings
peerIdleTimeout time.Duration // maximum period between sending frames
@ -1022,58 +1023,58 @@ func parseProtoHeader(r *buffer.Buffer) (protoHeader, error) {
func parseFrameBody(r *buffer.Buffer) (frameBody, error) {
payload := r.Bytes()
if r.Len() < 3 || payload[0] != 0 || amqpType(payload[1]) != typeCodeSmallUlong {
if r.Len() < 3 || payload[0] != 0 || encoding.AMQPType(payload[1]) != encoding.TypeCodeSmallUlong {
return nil, errors.New("invalid frame body header")
}
switch pType := amqpType(payload[2]); pType {
case typeCodeOpen:
switch pType := encoding.AMQPType(payload[2]); pType {
case encoding.TypeCodeOpen:
t := new(performOpen)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeBegin:
case encoding.TypeCodeBegin:
t := new(performBegin)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeAttach:
case encoding.TypeCodeAttach:
t := new(performAttach)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeFlow:
case encoding.TypeCodeFlow:
t := new(performFlow)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeTransfer:
case encoding.TypeCodeTransfer:
t := new(performTransfer)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeDisposition:
case encoding.TypeCodeDisposition:
t := new(performDisposition)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeDetach:
case encoding.TypeCodeDetach:
t := new(performDetach)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeEnd:
case encoding.TypeCodeEnd:
t := new(performEnd)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeClose:
case encoding.TypeCodeClose:
t := new(performClose)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeSASLMechanism:
case encoding.TypeCodeSASLMechanism:
t := new(saslMechanisms)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeSASLChallenge:
case encoding.TypeCodeSASLChallenge:
t := new(saslChallenge)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
case typeCodeSASLOutcome:
case encoding.TypeCodeSASLOutcome:
t := new(saslOutcome)
err := t.unmarshal(r)
err := t.Unmarshal(r)
return t, err
default:
return nil, fmt.Errorf("unknown preformative type %02x", pType)
@ -1091,7 +1092,7 @@ func writeFrame(buf *buffer.Buffer, fr frame) error {
buf.AppendUint16(fr.channel) // channel
// write AMQP frame body
err := marshal(buf, fr.body)
err := encoding.Marshal(buf, fr.body)
if err != nil {
return err
}

Просмотреть файл

@ -2,6 +2,8 @@ package amqp
import (
"testing"
"github.com/Azure/go-amqp/internal/encoding"
)
func TestConnOptions(t *testing.T) {
@ -9,7 +11,7 @@ func TestConnOptions(t *testing.T) {
label string
opts []ConnOption
wantProperties map[symbol]interface{}
wantProperties map[encoding.Symbol]interface{}
}{
{
label: "no options",
@ -22,7 +24,7 @@ func TestConnOptions(t *testing.T) {
ConnProperty("x-opt-test1", "test3"),
},
wantProperties: map[symbol]interface{}{
wantProperties: map[encoding.Symbol]interface{}{
"x-opt-test1": "test3",
"x-opt-test2": "test2",
},

Просмотреть файл

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/Azure/go-amqp/internal/buffer"
"github.com/Azure/go-amqp/internal/encoding"
)
// Sender Settlement Modes
@ -41,12 +42,12 @@ func (m *SenderSettleMode) String() string {
}
}
func (m SenderSettleMode) marshal(wr *buffer.Buffer) error {
return marshal(wr, uint8(m))
func (m SenderSettleMode) Marshal(wr *buffer.Buffer) error {
return encoding.Marshal(wr, uint8(m))
}
func (m *SenderSettleMode) unmarshal(r *buffer.Buffer) error {
n, err := readUbyte(r)
func (m *SenderSettleMode) Unmarshal(r *buffer.Buffer) error {
n, err := encoding.ReadUbyte(r)
*m = SenderSettleMode(n)
return err
}
@ -89,12 +90,12 @@ func (m *ReceiverSettleMode) String() string {
}
}
func (m ReceiverSettleMode) marshal(wr *buffer.Buffer) error {
return marshal(wr, uint8(m))
func (m ReceiverSettleMode) Marshal(wr *buffer.Buffer) error {
return encoding.Marshal(wr, uint8(m))
}
func (m *ReceiverSettleMode) unmarshal(r *buffer.Buffer) error {
n, err := readUbyte(r)
func (m *ReceiverSettleMode) Unmarshal(r *buffer.Buffer) error {
n, err := encoding.ReadUbyte(r)
*m = ReceiverSettleMode(n)
return err
}
@ -141,12 +142,12 @@ func (d *Durability) String() string {
}
}
func (d Durability) marshal(wr *buffer.Buffer) error {
return marshal(wr, uint32(d))
func (d Durability) Marshal(wr *buffer.Buffer) error {
return encoding.Marshal(wr, uint32(d))
}
func (d *Durability) unmarshal(r *buffer.Buffer) error {
return unmarshal(r, (*uint32)(d))
func (d *Durability) Unmarshal(r *buffer.Buffer) error {
return encoding.Unmarshal(r, (*uint32)(d))
}
// Expiry Policies
@ -173,7 +174,7 @@ const (
// then the count down is aborted. If the conditions for the
// terminus-expiry-policy are subsequently re-met, the expiry timer restarts
// from its originally configured timeout value.
type ExpiryPolicy symbol
type ExpiryPolicy encoding.Symbol
func (e ExpiryPolicy) validate() error {
switch e {
@ -187,12 +188,12 @@ func (e ExpiryPolicy) validate() error {
}
}
func (e ExpiryPolicy) marshal(wr *buffer.Buffer) error {
return symbol(e).marshal(wr)
func (e ExpiryPolicy) Marshal(wr *buffer.Buffer) error {
return encoding.Symbol(e).Marshal(wr)
}
func (e *ExpiryPolicy) unmarshal(r *buffer.Buffer) error {
err := unmarshal(r, (*symbol)(e))
func (e *ExpiryPolicy) Unmarshal(r *buffer.Buffer) error {
err := encoding.Unmarshal(r, (*encoding.Symbol)(e))
if err != nil {
return err
}

Просмотреть файл

@ -1,24 +1,6 @@
package amqp
import (
"errors"
"fmt"
"github.com/Azure/go-amqp/internal/buffer"
)
// ErrorCondition is one of the error conditions defined in the AMQP spec.
type ErrorCondition string
func (ec ErrorCondition) marshal(wr *buffer.Buffer) error {
return (symbol)(ec).marshal(wr)
}
func (ec *ErrorCondition) unmarshal(r *buffer.Buffer) error {
s, err := readString(r)
*ec = ErrorCondition(s)
return err
}
import "github.com/Azure/go-amqp/internal/encoding"
// Error Conditions
const (
@ -56,57 +38,6 @@ const (
ErrorStolen ErrorCondition = "amqp:link:stolen"
)
/*
<type name="error" class="composite" source="list">
<descriptor name="amqp:error:list" code="0x00000000:0x0000001d"/>
<field name="condition" type="symbol" requires="error-condition" mandatory="true"/>
<field name="description" type="string"/>
<field name="info" type="fields"/>
</type>
*/
type Error = encoding.Error
// Error is an AMQP error.
type Error struct {
// A symbolic value indicating the error condition.
Condition ErrorCondition
// descriptive text about the error condition
//
// This text supplies any supplementary details not indicated by the condition field.
// This text can be logged as an aid to resolving issues.
Description string
// map carrying information about the error condition
Info map[string]interface{}
}
func (e *Error) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeError, []marshalField{
{value: &e.Condition, omit: false},
{value: &e.Description, omit: e.Description == ""},
{value: e.Info, omit: len(e.Info) == 0},
})
}
func (e *Error) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeError, []unmarshalField{
{field: &e.Condition, handleNull: func() error { return errors.New("Error.Condition is required") }},
{field: &e.Description},
{field: &e.Info},
}...)
}
func (e *Error) String() string {
if e == nil {
return "*Error(nil)"
}
return fmt.Sprintf("*Error{Condition: %s, Description: %s, Info: %v}",
e.Condition,
e.Description,
e.Info,
)
}
func (e *Error) Error() string {
return e.String()
}
type ErrorCondition = encoding.ErrorCondition

545
frames.go
Просмотреть файл

@ -7,6 +7,7 @@ import (
"time"
"github.com/Azure/go-amqp/internal/buffer"
"github.com/Azure/go-amqp/internal/encoding"
)
/*
@ -102,14 +103,14 @@ type source struct {
// distribution-modes. That is, the value MUST be of the same type as
// would be valid in a field defined with the following attributes:
// type="symbol" multiple="true" requires="distribution-mode"
DynamicNodeProperties map[symbol]interface{} // TODO: implement custom type with validation
DynamicNodeProperties map[encoding.Symbol]interface{} // TODO: implement custom type with validation
// the distribution mode of the link
//
// This field MUST be set by the sending end of the link if the endpoint supports more
// than one distribution-mode. This field MAY be set by the receiving end of the link
// to indicate a preference when a node supports multiple distribution modes.
DistributionMode symbol
DistributionMode encoding.Symbol
// a set of predicates to filter the messages admitted onto the link
//
@ -117,7 +118,7 @@ type source struct {
// actually in place (including any filters defaulted at the node). The receiving
// endpoint MUST check that the filter in place meets its needs and take responsibility
// for detaching if it does not.
Filter filter
Filter encoding.Filter
// default outcome for unsettled transfers
//
@ -135,43 +136,43 @@ type source struct {
//
// When present, the values MUST be a symbolic descriptor of a valid outcome,
// e.g., "amqp:accepted:list".
Outcomes multiSymbol
Outcomes encoding.MultiSymbol
// the extension capabilities the sender supports/desires
//
// http://www.amqp.org/specification/1.0/source-capabilities
Capabilities multiSymbol
Capabilities encoding.MultiSymbol
}
func (s *source) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeSource, []marshalField{
{value: &s.Address, omit: s.Address == ""},
{value: &s.Durable, omit: s.Durable == DurabilityNone},
{value: &s.ExpiryPolicy, omit: s.ExpiryPolicy == "" || s.ExpiryPolicy == ExpirySessionEnd},
{value: &s.Timeout, omit: s.Timeout == 0},
{value: &s.Dynamic, omit: !s.Dynamic},
{value: s.DynamicNodeProperties, omit: len(s.DynamicNodeProperties) == 0},
{value: &s.DistributionMode, omit: s.DistributionMode == ""},
{value: s.Filter, omit: len(s.Filter) == 0},
{value: &s.DefaultOutcome, omit: s.DefaultOutcome == nil},
{value: &s.Outcomes, omit: len(s.Outcomes) == 0},
{value: &s.Capabilities, omit: len(s.Capabilities) == 0},
func (s *source) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeSource, []encoding.MarshalField{
{Value: &s.Address, Omit: s.Address == ""},
{Value: &s.Durable, Omit: s.Durable == DurabilityNone},
{Value: &s.ExpiryPolicy, Omit: s.ExpiryPolicy == "" || s.ExpiryPolicy == ExpirySessionEnd},
{Value: &s.Timeout, Omit: s.Timeout == 0},
{Value: &s.Dynamic, Omit: !s.Dynamic},
{Value: s.DynamicNodeProperties, Omit: len(s.DynamicNodeProperties) == 0},
{Value: &s.DistributionMode, Omit: s.DistributionMode == ""},
{Value: s.Filter, Omit: len(s.Filter) == 0},
{Value: &s.DefaultOutcome, Omit: s.DefaultOutcome == nil},
{Value: &s.Outcomes, Omit: len(s.Outcomes) == 0},
{Value: &s.Capabilities, Omit: len(s.Capabilities) == 0},
})
}
func (s *source) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeSource, []unmarshalField{
{field: &s.Address},
{field: &s.Durable},
{field: &s.ExpiryPolicy, handleNull: func() error { s.ExpiryPolicy = ExpirySessionEnd; return nil }},
{field: &s.Timeout},
{field: &s.Dynamic},
{field: &s.DynamicNodeProperties},
{field: &s.DistributionMode},
{field: &s.Filter},
{field: &s.DefaultOutcome},
{field: &s.Outcomes},
{field: &s.Capabilities},
func (s *source) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeSource, []encoding.UnmarshalField{
{Field: &s.Address},
{Field: &s.Durable},
{Field: &s.ExpiryPolicy, HandleNull: func() error { s.ExpiryPolicy = ExpirySessionEnd; return nil }},
{Field: &s.Timeout},
{Field: &s.Dynamic},
{Field: &s.DynamicNodeProperties},
{Field: &s.DistributionMode},
{Field: &s.Filter},
{Field: &s.DefaultOutcome},
{Field: &s.Outcomes},
{Field: &s.Capabilities},
}...)
}
@ -282,35 +283,35 @@ type target struct {
// distribution-modes. That is, the value MUST be of the same type as
// would be valid in a field defined with the following attributes:
// type="symbol" multiple="true" requires="distribution-mode"
DynamicNodeProperties map[symbol]interface{} // TODO: implement custom type with validation
DynamicNodeProperties map[encoding.Symbol]interface{} // TODO: implement custom type with validation
// the extension capabilities the sender supports/desires
//
// http://www.amqp.org/specification/1.0/target-capabilities
Capabilities multiSymbol
Capabilities encoding.MultiSymbol
}
func (t *target) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeTarget, []marshalField{
{value: &t.Address, omit: t.Address == ""},
{value: &t.Durable, omit: t.Durable == DurabilityNone},
{value: &t.ExpiryPolicy, omit: t.ExpiryPolicy == "" || t.ExpiryPolicy == ExpirySessionEnd},
{value: &t.Timeout, omit: t.Timeout == 0},
{value: &t.Dynamic, omit: !t.Dynamic},
{value: t.DynamicNodeProperties, omit: len(t.DynamicNodeProperties) == 0},
{value: &t.Capabilities, omit: len(t.Capabilities) == 0},
func (t *target) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeTarget, []encoding.MarshalField{
{Value: &t.Address, Omit: t.Address == ""},
{Value: &t.Durable, Omit: t.Durable == DurabilityNone},
{Value: &t.ExpiryPolicy, Omit: t.ExpiryPolicy == "" || t.ExpiryPolicy == ExpirySessionEnd},
{Value: &t.Timeout, Omit: t.Timeout == 0},
{Value: &t.Dynamic, Omit: !t.Dynamic},
{Value: t.DynamicNodeProperties, Omit: len(t.DynamicNodeProperties) == 0},
{Value: &t.Capabilities, Omit: len(t.Capabilities) == 0},
})
}
func (t *target) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeTarget, []unmarshalField{
{field: &t.Address},
{field: &t.Durable},
{field: &t.ExpiryPolicy, handleNull: func() error { t.ExpiryPolicy = ExpirySessionEnd; return nil }},
{field: &t.Timeout},
{field: &t.Dynamic},
{field: &t.DynamicNodeProperties},
{field: &t.Capabilities},
func (t *target) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeTarget, []encoding.UnmarshalField{
{Field: &t.Address},
{Field: &t.Durable},
{Field: &t.ExpiryPolicy, HandleNull: func() error { t.ExpiryPolicy = ExpirySessionEnd; return nil }},
{Field: &t.Timeout},
{Field: &t.Dynamic},
{Field: &t.DynamicNodeProperties},
{Field: &t.Capabilities},
}...)
}
@ -334,7 +335,7 @@ type frame struct {
body frameBody // body of the frame
// optional channel which will be closed after net transmit
done chan deliveryState
done chan encoding.DeliveryState
}
// frameBody adds some type safety to frame encoding
@ -364,42 +365,42 @@ type performOpen struct {
MaxFrameSize uint32 // default: 4294967295
ChannelMax uint16 // default: 65535
IdleTimeout time.Duration // from milliseconds
OutgoingLocales multiSymbol
IncomingLocales multiSymbol
OfferedCapabilities multiSymbol
DesiredCapabilities multiSymbol
Properties map[symbol]interface{}
OutgoingLocales encoding.MultiSymbol
IncomingLocales encoding.MultiSymbol
OfferedCapabilities encoding.MultiSymbol
DesiredCapabilities encoding.MultiSymbol
Properties map[encoding.Symbol]interface{}
}
func (o *performOpen) frameBody() {}
func (o *performOpen) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeOpen, []marshalField{
{value: &o.ContainerID, omit: false},
{value: &o.Hostname, omit: o.Hostname == ""},
{value: &o.MaxFrameSize, omit: o.MaxFrameSize == 4294967295},
{value: &o.ChannelMax, omit: o.ChannelMax == 65535},
{value: (*milliseconds)(&o.IdleTimeout), omit: o.IdleTimeout == 0},
{value: &o.OutgoingLocales, omit: len(o.OutgoingLocales) == 0},
{value: &o.IncomingLocales, omit: len(o.IncomingLocales) == 0},
{value: &o.OfferedCapabilities, omit: len(o.OfferedCapabilities) == 0},
{value: &o.DesiredCapabilities, omit: len(o.DesiredCapabilities) == 0},
{value: o.Properties, omit: len(o.Properties) == 0},
func (o *performOpen) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeOpen, []encoding.MarshalField{
{Value: &o.ContainerID, Omit: false},
{Value: &o.Hostname, Omit: o.Hostname == ""},
{Value: &o.MaxFrameSize, Omit: o.MaxFrameSize == 4294967295},
{Value: &o.ChannelMax, Omit: o.ChannelMax == 65535},
{Value: (*encoding.Milliseconds)(&o.IdleTimeout), Omit: o.IdleTimeout == 0},
{Value: &o.OutgoingLocales, Omit: len(o.OutgoingLocales) == 0},
{Value: &o.IncomingLocales, Omit: len(o.IncomingLocales) == 0},
{Value: &o.OfferedCapabilities, Omit: len(o.OfferedCapabilities) == 0},
{Value: &o.DesiredCapabilities, Omit: len(o.DesiredCapabilities) == 0},
{Value: o.Properties, Omit: len(o.Properties) == 0},
})
}
func (o *performOpen) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeOpen, []unmarshalField{
{field: &o.ContainerID, handleNull: func() error { return errors.New("Open.ContainerID is required") }},
{field: &o.Hostname},
{field: &o.MaxFrameSize, handleNull: func() error { o.MaxFrameSize = 4294967295; return nil }},
{field: &o.ChannelMax, handleNull: func() error { o.ChannelMax = 65535; return nil }},
{field: (*milliseconds)(&o.IdleTimeout)},
{field: &o.OutgoingLocales},
{field: &o.IncomingLocales},
{field: &o.OfferedCapabilities},
{field: &o.DesiredCapabilities},
{field: &o.Properties},
func (o *performOpen) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeOpen, []encoding.UnmarshalField{
{Field: &o.ContainerID, HandleNull: func() error { return errors.New("Open.ContainerID is required") }},
{Field: &o.Hostname},
{Field: &o.MaxFrameSize, HandleNull: func() error { o.MaxFrameSize = 4294967295; return nil }},
{Field: &o.ChannelMax, HandleNull: func() error { o.ChannelMax = 65535; return nil }},
{Field: (*encoding.Milliseconds)(&o.IdleTimeout)},
{Field: &o.OutgoingLocales},
{Field: &o.IncomingLocales},
{Field: &o.OfferedCapabilities},
{Field: &o.DesiredCapabilities},
{Field: &o.Properties},
}...)
}
@ -461,16 +462,16 @@ type performBegin struct {
// the extension capabilities the sender supports
// http://www.amqp.org/specification/1.0/session-capabilities
OfferedCapabilities multiSymbol
OfferedCapabilities encoding.MultiSymbol
// the extension capabilities the sender can use if the receiver supports them
// The sender MUST NOT attempt to use any capability other than those it
// has declared in desired-capabilities field.
DesiredCapabilities multiSymbol
DesiredCapabilities encoding.MultiSymbol
// session properties
// http://www.amqp.org/specification/1.0/session-properties
Properties map[symbol]interface{}
Properties map[encoding.Symbol]interface{}
}
func (b *performBegin) frameBody() {}
@ -497,29 +498,29 @@ func formatUint16Ptr(p *uint16) string {
return strconv.FormatUint(uint64(*p), 10)
}
func (b *performBegin) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeBegin, []marshalField{
{value: b.RemoteChannel, omit: b.RemoteChannel == nil},
{value: &b.NextOutgoingID, omit: false},
{value: &b.IncomingWindow, omit: false},
{value: &b.OutgoingWindow, omit: false},
{value: &b.HandleMax, omit: b.HandleMax == 4294967295},
{value: &b.OfferedCapabilities, omit: len(b.OfferedCapabilities) == 0},
{value: &b.DesiredCapabilities, omit: len(b.DesiredCapabilities) == 0},
{value: b.Properties, omit: b.Properties == nil},
func (b *performBegin) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeBegin, []encoding.MarshalField{
{Value: b.RemoteChannel, Omit: b.RemoteChannel == nil},
{Value: &b.NextOutgoingID, Omit: false},
{Value: &b.IncomingWindow, Omit: false},
{Value: &b.OutgoingWindow, Omit: false},
{Value: &b.HandleMax, Omit: b.HandleMax == 4294967295},
{Value: &b.OfferedCapabilities, Omit: len(b.OfferedCapabilities) == 0},
{Value: &b.DesiredCapabilities, Omit: len(b.DesiredCapabilities) == 0},
{Value: b.Properties, Omit: b.Properties == nil},
})
}
func (b *performBegin) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeBegin, []unmarshalField{
{field: &b.RemoteChannel},
{field: &b.NextOutgoingID, handleNull: func() error { return errors.New("Begin.NextOutgoingID is required") }},
{field: &b.IncomingWindow, handleNull: func() error { return errors.New("Begin.IncomingWindow is required") }},
{field: &b.OutgoingWindow, handleNull: func() error { return errors.New("Begin.OutgoingWindow is required") }},
{field: &b.HandleMax, handleNull: func() error { b.HandleMax = 4294967295; return nil }},
{field: &b.OfferedCapabilities},
{field: &b.DesiredCapabilities},
{field: &b.Properties},
func (b *performBegin) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeBegin, []encoding.UnmarshalField{
{Field: &b.RemoteChannel},
{Field: &b.NextOutgoingID, HandleNull: func() error { return errors.New("Begin.NextOutgoingID is required") }},
{Field: &b.IncomingWindow, HandleNull: func() error { return errors.New("Begin.IncomingWindow is required") }},
{Field: &b.OutgoingWindow, HandleNull: func() error { return errors.New("Begin.OutgoingWindow is required") }},
{Field: &b.HandleMax, HandleNull: func() error { b.HandleMax = 4294967295; return nil }},
{Field: &b.OfferedCapabilities},
{Field: &b.DesiredCapabilities},
{Field: &b.Properties},
}...)
}
@ -628,7 +629,7 @@ type performAttach struct {
// The unsettled map MUST NOT contain null valued keys.
//
// When reattaching (as opposed to resuming), the unsettled map MUST be null.
Unsettled unsettled
Unsettled encoding.Unsettled
// If set to true this field indicates that the unsettled map provided is not complete.
// When the map is incomplete the recipient of the map cannot take the absence of a
@ -660,17 +661,17 @@ type performAttach struct {
// the extension capabilities the sender supports
// http://www.amqp.org/specification/1.0/link-capabilities
OfferedCapabilities multiSymbol
OfferedCapabilities encoding.MultiSymbol
// the extension capabilities the sender can use if the receiver supports them
//
// The sender MUST NOT attempt to use any capability other than those it
// has declared in desired-capabilities field.
DesiredCapabilities multiSymbol
DesiredCapabilities encoding.MultiSymbol
// link properties
// http://www.amqp.org/specification/1.0/link-properties
Properties map[symbol]interface{}
Properties map[encoding.Symbol]interface{}
}
func (a *performAttach) frameBody() {}
@ -696,41 +697,41 @@ func (a performAttach) String() string {
)
}
func (a *performAttach) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeAttach, []marshalField{
{value: &a.Name, omit: false},
{value: &a.Handle, omit: false},
{value: &a.Role, omit: false},
{value: a.SenderSettleMode, omit: a.SenderSettleMode == nil},
{value: a.ReceiverSettleMode, omit: a.ReceiverSettleMode == nil},
{value: a.Source, omit: a.Source == nil},
{value: a.Target, omit: a.Target == nil},
{value: a.Unsettled, omit: len(a.Unsettled) == 0},
{value: &a.IncompleteUnsettled, omit: !a.IncompleteUnsettled},
{value: &a.InitialDeliveryCount, omit: a.Role == roleReceiver},
{value: &a.MaxMessageSize, omit: a.MaxMessageSize == 0},
{value: &a.OfferedCapabilities, omit: len(a.OfferedCapabilities) == 0},
{value: &a.DesiredCapabilities, omit: len(a.DesiredCapabilities) == 0},
{value: a.Properties, omit: len(a.Properties) == 0},
func (a *performAttach) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeAttach, []encoding.MarshalField{
{Value: &a.Name, Omit: false},
{Value: &a.Handle, Omit: false},
{Value: &a.Role, Omit: false},
{Value: a.SenderSettleMode, Omit: a.SenderSettleMode == nil},
{Value: a.ReceiverSettleMode, Omit: a.ReceiverSettleMode == nil},
{Value: a.Source, Omit: a.Source == nil},
{Value: a.Target, Omit: a.Target == nil},
{Value: a.Unsettled, Omit: len(a.Unsettled) == 0},
{Value: &a.IncompleteUnsettled, Omit: !a.IncompleteUnsettled},
{Value: &a.InitialDeliveryCount, Omit: a.Role == roleReceiver},
{Value: &a.MaxMessageSize, Omit: a.MaxMessageSize == 0},
{Value: &a.OfferedCapabilities, Omit: len(a.OfferedCapabilities) == 0},
{Value: &a.DesiredCapabilities, Omit: len(a.DesiredCapabilities) == 0},
{Value: a.Properties, Omit: len(a.Properties) == 0},
})
}
func (a *performAttach) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeAttach, []unmarshalField{
{field: &a.Name, handleNull: func() error { return errors.New("Attach.Name is required") }},
{field: &a.Handle, handleNull: func() error { return errors.New("Attach.Handle is required") }},
{field: &a.Role, handleNull: func() error { return errors.New("Attach.Role is required") }},
{field: &a.SenderSettleMode},
{field: &a.ReceiverSettleMode},
{field: &a.Source},
{field: &a.Target},
{field: &a.Unsettled},
{field: &a.IncompleteUnsettled},
{field: &a.InitialDeliveryCount},
{field: &a.MaxMessageSize},
{field: &a.OfferedCapabilities},
{field: &a.DesiredCapabilities},
{field: &a.Properties},
func (a *performAttach) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeAttach, []encoding.UnmarshalField{
{Field: &a.Name, HandleNull: func() error { return errors.New("Attach.Name is required") }},
{Field: &a.Handle, HandleNull: func() error { return errors.New("Attach.Handle is required") }},
{Field: &a.Role, HandleNull: func() error { return errors.New("Attach.Role is required") }},
{Field: &a.SenderSettleMode},
{Field: &a.ReceiverSettleMode},
{Field: &a.Source},
{Field: &a.Target},
{Field: &a.Unsettled},
{Field: &a.IncompleteUnsettled},
{Field: &a.InitialDeliveryCount},
{Field: &a.MaxMessageSize},
{Field: &a.OfferedCapabilities},
{Field: &a.DesiredCapabilities},
{Field: &a.Properties},
}...)
}
@ -846,7 +847,7 @@ type performFlow struct {
// link state properties
// http://www.amqp.org/specification/1.0/link-state-properties
Properties map[symbol]interface{}
Properties map[encoding.Symbol]interface{}
}
func (f *performFlow) frameBody() {}
@ -875,35 +876,35 @@ func formatUint32Ptr(p *uint32) string {
return strconv.FormatUint(uint64(*p), 10)
}
func (f *performFlow) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeFlow, []marshalField{
{value: f.NextIncomingID, omit: f.NextIncomingID == nil},
{value: &f.IncomingWindow, omit: false},
{value: &f.NextOutgoingID, omit: false},
{value: &f.OutgoingWindow, omit: false},
{value: f.Handle, omit: f.Handle == nil},
{value: f.DeliveryCount, omit: f.DeliveryCount == nil},
{value: f.LinkCredit, omit: f.LinkCredit == nil},
{value: f.Available, omit: f.Available == nil},
{value: &f.Drain, omit: !f.Drain},
{value: &f.Echo, omit: !f.Echo},
{value: f.Properties, omit: len(f.Properties) == 0},
func (f *performFlow) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeFlow, []encoding.MarshalField{
{Value: f.NextIncomingID, Omit: f.NextIncomingID == nil},
{Value: &f.IncomingWindow, Omit: false},
{Value: &f.NextOutgoingID, Omit: false},
{Value: &f.OutgoingWindow, Omit: false},
{Value: f.Handle, Omit: f.Handle == nil},
{Value: f.DeliveryCount, Omit: f.DeliveryCount == nil},
{Value: f.LinkCredit, Omit: f.LinkCredit == nil},
{Value: f.Available, Omit: f.Available == nil},
{Value: &f.Drain, Omit: !f.Drain},
{Value: &f.Echo, Omit: !f.Echo},
{Value: f.Properties, Omit: len(f.Properties) == 0},
})
}
func (f *performFlow) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeFlow, []unmarshalField{
{field: &f.NextIncomingID},
{field: &f.IncomingWindow, handleNull: func() error { return errors.New("Flow.IncomingWindow is required") }},
{field: &f.NextOutgoingID, handleNull: func() error { return errors.New("Flow.NextOutgoingID is required") }},
{field: &f.OutgoingWindow, handleNull: func() error { return errors.New("Flow.OutgoingWindow is required") }},
{field: &f.Handle},
{field: &f.DeliveryCount},
{field: &f.LinkCredit},
{field: &f.Available},
{field: &f.Drain},
{field: &f.Echo},
{field: &f.Properties},
func (f *performFlow) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeFlow, []encoding.UnmarshalField{
{Field: &f.NextIncomingID},
{Field: &f.IncomingWindow, HandleNull: func() error { return errors.New("Flow.IncomingWindow is required") }},
{Field: &f.NextOutgoingID, HandleNull: func() error { return errors.New("Flow.NextOutgoingID is required") }},
{Field: &f.OutgoingWindow, HandleNull: func() error { return errors.New("Flow.OutgoingWindow is required") }},
{Field: &f.Handle},
{Field: &f.DeliveryCount},
{Field: &f.LinkCredit},
{Field: &f.Available},
{Field: &f.Drain},
{Field: &f.Echo},
{Field: &f.Properties},
}...)
}
@ -1011,7 +1012,7 @@ type performTransfer struct {
// referring to the delivery) indicates that the delivery has attained a terminal
// state, then no future transfer or disposition sent by the sender can alter that
// terminal state.
State deliveryState
State encoding.DeliveryState
// indicates a resumed delivery
//
@ -1064,7 +1065,7 @@ type performTransfer struct {
//
// Settled=true: closed when the transferred on network.
// Settled=false: closed when the receiver has confirmed settlement.
done chan deliveryState
done chan encoding.DeliveryState
}
func (t *performTransfer) frameBody() {}
@ -1093,19 +1094,19 @@ func (t performTransfer) String() string {
)
}
func (t *performTransfer) marshal(wr *buffer.Buffer) error {
err := marshalComposite(wr, typeCodeTransfer, []marshalField{
{value: &t.Handle},
{value: t.DeliveryID, omit: t.DeliveryID == nil},
{value: &t.DeliveryTag, omit: len(t.DeliveryTag) == 0},
{value: t.MessageFormat, omit: t.MessageFormat == nil},
{value: &t.Settled, omit: !t.Settled},
{value: &t.More, omit: !t.More},
{value: t.ReceiverSettleMode, omit: t.ReceiverSettleMode == nil},
{value: t.State, omit: t.State == nil},
{value: &t.Resume, omit: !t.Resume},
{value: &t.Aborted, omit: !t.Aborted},
{value: &t.Batchable, omit: !t.Batchable},
func (t *performTransfer) Marshal(wr *buffer.Buffer) error {
err := encoding.MarshalComposite(wr, encoding.TypeCodeTransfer, []encoding.MarshalField{
{Value: &t.Handle},
{Value: t.DeliveryID, Omit: t.DeliveryID == nil},
{Value: &t.DeliveryTag, Omit: len(t.DeliveryTag) == 0},
{Value: t.MessageFormat, Omit: t.MessageFormat == nil},
{Value: &t.Settled, Omit: !t.Settled},
{Value: &t.More, Omit: !t.More},
{Value: t.ReceiverSettleMode, Omit: t.ReceiverSettleMode == nil},
{Value: t.State, Omit: t.State == nil},
{Value: &t.Resume, Omit: !t.Resume},
{Value: &t.Aborted, Omit: !t.Aborted},
{Value: &t.Batchable, Omit: !t.Batchable},
})
if err != nil {
return err
@ -1115,19 +1116,19 @@ func (t *performTransfer) marshal(wr *buffer.Buffer) error {
return nil
}
func (t *performTransfer) unmarshal(r *buffer.Buffer) error {
err := unmarshalComposite(r, typeCodeTransfer, []unmarshalField{
{field: &t.Handle, handleNull: func() error { return errors.New("Transfer.Handle is required") }},
{field: &t.DeliveryID},
{field: &t.DeliveryTag},
{field: &t.MessageFormat},
{field: &t.Settled},
{field: &t.More},
{field: &t.ReceiverSettleMode},
{field: &t.State},
{field: &t.Resume},
{field: &t.Aborted},
{field: &t.Batchable},
func (t *performTransfer) Unmarshal(r *buffer.Buffer) error {
err := encoding.UnmarshalComposite(r, encoding.TypeCodeTransfer, []encoding.UnmarshalField{
{Field: &t.Handle, HandleNull: func() error { return errors.New("Transfer.Handle is required") }},
{Field: &t.DeliveryID},
{Field: &t.DeliveryTag},
{Field: &t.MessageFormat},
{Field: &t.Settled},
{Field: &t.More},
{Field: &t.ReceiverSettleMode},
{Field: &t.State},
{Field: &t.Resume},
{Field: &t.Aborted},
{Field: &t.Batchable},
}...)
if err != nil {
return err
@ -1176,7 +1177,7 @@ type performDisposition struct {
// indicates state of deliveries
//
// Communicates the state of all the deliveries referenced by this disposition.
State deliveryState
State encoding.DeliveryState
// batchable hint
//
@ -1200,25 +1201,25 @@ func (d performDisposition) String() string {
)
}
func (d *performDisposition) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeDisposition, []marshalField{
{value: &d.Role, omit: false},
{value: &d.First, omit: false},
{value: d.Last, omit: d.Last == nil},
{value: &d.Settled, omit: !d.Settled},
{value: d.State, omit: d.State == nil},
{value: &d.Batchable, omit: !d.Batchable},
func (d *performDisposition) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeDisposition, []encoding.MarshalField{
{Value: &d.Role, Omit: false},
{Value: &d.First, Omit: false},
{Value: d.Last, Omit: d.Last == nil},
{Value: &d.Settled, Omit: !d.Settled},
{Value: d.State, Omit: d.State == nil},
{Value: &d.Batchable, Omit: !d.Batchable},
})
}
func (d *performDisposition) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeDisposition, []unmarshalField{
{field: &d.Role, handleNull: func() error { return errors.New("Disposition.Role is required") }},
{field: &d.First, handleNull: func() error { return errors.New("Disposition.Handle is required") }},
{field: &d.Last},
{field: &d.Settled},
{field: &d.State},
{field: &d.Batchable},
func (d *performDisposition) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeDisposition, []encoding.UnmarshalField{
{Field: &d.Role, HandleNull: func() error { return errors.New("Disposition.Role is required") }},
{Field: &d.First, HandleNull: func() error { return errors.New("Disposition.Handle is required") }},
{Field: &d.Last},
{Field: &d.Settled},
{Field: &d.State},
{Field: &d.Batchable},
}...)
}
@ -1254,19 +1255,19 @@ func (d performDetach) String() string {
)
}
func (d *performDetach) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeDetach, []marshalField{
{value: &d.Handle, omit: false},
{value: &d.Closed, omit: !d.Closed},
{value: d.Error, omit: d.Error == nil},
func (d *performDetach) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeDetach, []encoding.MarshalField{
{Value: &d.Handle, Omit: false},
{Value: &d.Closed, Omit: !d.Closed},
{Value: d.Error, Omit: d.Error == nil},
})
}
func (d *performDetach) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeDetach, []unmarshalField{
{field: &d.Handle, handleNull: func() error { return errors.New("Detach.Handle is required") }},
{field: &d.Closed},
{field: &d.Error},
func (d *performDetach) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeDetach, []encoding.UnmarshalField{
{Field: &d.Handle, HandleNull: func() error { return errors.New("Detach.Handle is required") }},
{Field: &d.Closed},
{Field: &d.Error},
}...)
}
@ -1286,15 +1287,15 @@ type performEnd struct {
func (e *performEnd) frameBody() {}
func (e *performEnd) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeEnd, []marshalField{
{value: e.Error, omit: e.Error == nil},
func (e *performEnd) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeEnd, []encoding.MarshalField{
{Value: e.Error, Omit: e.Error == nil},
})
}
func (e *performEnd) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeEnd,
unmarshalField{field: &e.Error},
func (e *performEnd) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeEnd,
encoding.UnmarshalField{Field: &e.Error},
)
}
@ -1314,15 +1315,15 @@ type performClose struct {
func (c *performClose) frameBody() {}
func (c *performClose) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeClose, []marshalField{
{value: c.Error, omit: c.Error == nil},
func (c *performClose) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeClose, []encoding.MarshalField{
{Value: c.Error, Omit: c.Error == nil},
})
}
func (c *performClose) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeClose,
unmarshalField{field: &c.Error},
func (c *performClose) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeClose,
encoding.UnmarshalField{Field: &c.Error},
)
}
@ -1340,26 +1341,26 @@ func (c *performClose) String() string {
*/
type saslInit struct {
Mechanism symbol
Mechanism encoding.Symbol
InitialResponse []byte
Hostname string
}
func (si *saslInit) frameBody() {}
func (si *saslInit) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeSASLInit, []marshalField{
{value: &si.Mechanism, omit: false},
{value: &si.InitialResponse, omit: len(si.InitialResponse) == 0},
{value: &si.Hostname, omit: len(si.Hostname) == 0},
func (si *saslInit) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeSASLInit, []encoding.MarshalField{
{Value: &si.Mechanism, Omit: false},
{Value: &si.InitialResponse, Omit: len(si.InitialResponse) == 0},
{Value: &si.Hostname, Omit: len(si.Hostname) == 0},
})
}
func (si *saslInit) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeSASLInit, []unmarshalField{
{field: &si.Mechanism, handleNull: func() error { return errors.New("saslInit.Mechanism is required") }},
{field: &si.InitialResponse},
{field: &si.Hostname},
func (si *saslInit) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeSASLInit, []encoding.UnmarshalField{
{Field: &si.Mechanism, HandleNull: func() error { return errors.New("saslInit.Mechanism is required") }},
{Field: &si.InitialResponse},
{Field: &si.Hostname},
}...)
}
@ -1379,20 +1380,20 @@ func (si *saslInit) String() string {
*/
type saslMechanisms struct {
Mechanisms multiSymbol
Mechanisms encoding.MultiSymbol
}
func (sm *saslMechanisms) frameBody() {}
func (sm *saslMechanisms) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeSASLMechanism, []marshalField{
{value: &sm.Mechanisms, omit: false},
func (sm *saslMechanisms) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeSASLMechanism, []encoding.MarshalField{
{Value: &sm.Mechanisms, Omit: false},
})
}
func (sm *saslMechanisms) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeSASLMechanism,
unmarshalField{field: &sm.Mechanisms, handleNull: func() error { return errors.New("saslMechanisms.Mechanisms is required") }},
func (sm *saslMechanisms) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeSASLMechanism,
encoding.UnmarshalField{Field: &sm.Mechanisms, HandleNull: func() error { return errors.New("saslMechanisms.Mechanisms is required") }},
)
}
@ -1419,15 +1420,15 @@ func (sc *saslChallenge) String() string {
func (sc *saslChallenge) frameBody() {}
func (sc *saslChallenge) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeSASLChallenge, []marshalField{
{value: &sc.Challenge, omit: false},
func (sc *saslChallenge) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeSASLChallenge, []encoding.MarshalField{
{Value: &sc.Challenge, Omit: false},
})
}
func (sc *saslChallenge) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeSASLChallenge, []unmarshalField{
{field: &sc.Challenge, handleNull: func() error { return errors.New("saslChallenge.Challenge is required") }},
func (sc *saslChallenge) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeSASLChallenge, []encoding.UnmarshalField{
{Field: &sc.Challenge, HandleNull: func() error { return errors.New("saslChallenge.Challenge is required") }},
}...)
}
@ -1448,15 +1449,15 @@ func (sr *saslResponse) String() string {
func (sr *saslResponse) frameBody() {}
func (sr *saslResponse) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeSASLResponse, []marshalField{
{value: &sr.Response, omit: false},
func (sr *saslResponse) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeSASLResponse, []encoding.MarshalField{
{Value: &sr.Response, Omit: false},
})
}
func (sr *saslResponse) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeSASLResponse, []unmarshalField{
{field: &sr.Response, handleNull: func() error { return errors.New("saslResponse.Response is required") }},
func (sr *saslResponse) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeSASLResponse, []encoding.UnmarshalField{
{Field: &sr.Response, HandleNull: func() error { return errors.New("saslResponse.Response is required") }},
}...)
}
@ -1475,17 +1476,17 @@ type saslOutcome struct {
func (so *saslOutcome) frameBody() {}
func (so *saslOutcome) marshal(wr *buffer.Buffer) error {
return marshalComposite(wr, typeCodeSASLOutcome, []marshalField{
{value: &so.Code, omit: false},
{value: &so.AdditionalData, omit: len(so.AdditionalData) == 0},
func (so *saslOutcome) Marshal(wr *buffer.Buffer) error {
return encoding.MarshalComposite(wr, encoding.TypeCodeSASLOutcome, []encoding.MarshalField{
{Value: &so.Code, Omit: false},
{Value: &so.AdditionalData, Omit: len(so.AdditionalData) == 0},
})
}
func (so *saslOutcome) unmarshal(r *buffer.Buffer) error {
return unmarshalComposite(r, typeCodeSASLOutcome, []unmarshalField{
{field: &so.Code, handleNull: func() error { return errors.New("saslOutcome.AdditionalData is required") }},
{field: &so.AdditionalData},
func (so *saslOutcome) Unmarshal(r *buffer.Buffer) error {
return encoding.UnmarshalComposite(r, encoding.TypeCodeSASLOutcome, []encoding.UnmarshalField{
{Field: &so.Code, HandleNull: func() error { return errors.New("saslOutcome.AdditionalData is required") }},
{Field: &so.AdditionalData},
}...)
}

Просмотреть файл

@ -10,6 +10,7 @@ import (
"time"
"github.com/Azure/go-amqp/internal/buffer"
"github.com/Azure/go-amqp/internal/encoding"
"github.com/Azure/go-amqp/internal/testconn"
"github.com/fortytw2/leaktest"
)
@ -110,8 +111,6 @@ func fuzzUnmarshal(data []byte) int {
new(*source),
new(target),
new(*target),
new(Error),
new(*Error),
new(saslCode),
new(*saslCode),
new(saslMechanisms),
@ -128,75 +127,13 @@ func fuzzUnmarshal(data []byte) int {
new(*MessageHeader),
new(MessageProperties),
new(*MessageProperties),
new(stateReceived),
new(*stateReceived),
new(stateAccepted),
new(*stateAccepted),
new(stateRejected),
new(*stateRejected),
new(stateReleased),
new(*stateReleased),
new(stateModified),
new(*stateModified),
new(mapAnyAny),
new(*mapAnyAny),
new(mapStringAny),
new(*mapStringAny),
new(mapSymbolAny),
new(*mapSymbolAny),
new(unsettled),
new(*unsettled),
new(milliseconds),
new(*milliseconds),
new(bool),
new(*bool),
new(int8),
new(*int8),
new(int16),
new(*int16),
new(int32),
new(*int32),
new(int64),
new(*int64),
new(uint8),
new(*uint8),
new(uint16),
new(*uint16),
new(uint32),
new(*uint32),
new(uint64),
new(*uint64),
new(time.Time),
new(*time.Time),
new(time.Duration),
new(*time.Duration),
new(symbol),
new(*symbol),
new([]byte),
new(*[]byte),
new([]string),
new(*[]string),
new([]symbol),
new(*[]symbol),
new(map[interface{}]interface{}),
new(*map[interface{}]interface{}),
new(map[string]interface{}),
new(*map[string]interface{}),
new(map[symbol]interface{}),
new(*map[symbol]interface{}),
new(interface{}),
new(*interface{}),
new(ErrorCondition),
new(*ErrorCondition),
new(role),
new(*role),
new(UUID),
new(*UUID),
}
for _, t := range types {
_ = unmarshal(buffer.New(data), t)
_, _ = readAny(buffer.New(data))
_ = encoding.Unmarshal(buffer.New(data), t)
_, _ = encoding.ReadAny(buffer.New(data))
}
return 0
}
@ -591,7 +528,7 @@ func TestFuzzConnCorpus(t *testing.T) {
t.Skip("set TEST_CORPUS to enable")
}
for _, path := range testDirFiles(t, "fuzz/conn/corpus") {
for _, path := range testDirFiles(t, "internal/encoding/testdata/fuzz/conn/corpus") {
t.Run(filepath.Base(path), func(t *testing.T) {
data, err := ioutil.ReadFile(path)
if err != nil {
@ -609,7 +546,7 @@ func TestFuzzMarshalCorpus(t *testing.T) {
t.Skip("set TEST_CORPUS to enable")
}
for _, path := range testDirFiles(t, "fuzz/marshal/corpus") {
for _, path := range testDirFiles(t, "internal/encoding/testdata/fuzz/marshal/corpus") {
t.Run(filepath.Base(path), func(t *testing.T) {
data, err := ioutil.ReadFile(path)
if err != nil {

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,4 @@
package amqp
package encoding
import (
"encoding/binary"
@ -12,24 +12,24 @@ import (
)
type marshaler interface {
marshal(*buffer.Buffer) error
Marshal(*buffer.Buffer) error
}
func marshal(wr *buffer.Buffer, i interface{}) error {
func Marshal(wr *buffer.Buffer, i interface{}) error {
switch t := i.(type) {
case nil:
wr.AppendByte(byte(typeCodeNull))
wr.AppendByte(byte(TypeCodeNull))
case bool:
if t {
wr.AppendByte(byte(typeCodeBoolTrue))
wr.AppendByte(byte(TypeCodeBoolTrue))
} else {
wr.AppendByte(byte(typeCodeBoolFalse))
wr.AppendByte(byte(TypeCodeBoolFalse))
}
case *bool:
if *t {
wr.AppendByte(byte(typeCodeBoolTrue))
wr.AppendByte(byte(TypeCodeBoolTrue))
} else {
wr.AppendByte(byte(typeCodeBoolFalse))
wr.AppendByte(byte(TypeCodeBoolFalse))
}
case uint:
writeUint64(wr, uint64(t))
@ -44,19 +44,19 @@ func marshal(wr *buffer.Buffer, i interface{}) error {
case *uint32:
writeUint32(wr, *t)
case uint16:
wr.AppendByte(byte(typeCodeUshort))
wr.AppendByte(byte(TypeCodeUshort))
wr.AppendUint16(t)
case *uint16:
wr.AppendByte(byte(typeCodeUshort))
wr.AppendByte(byte(TypeCodeUshort))
wr.AppendUint16(*t)
case uint8:
wr.Append([]byte{
byte(typeCodeUbyte),
byte(TypeCodeUbyte),
t,
})
case *uint8:
wr.Append([]byte{
byte(typeCodeUbyte),
byte(TypeCodeUbyte),
*t,
})
case int:
@ -65,19 +65,19 @@ func marshal(wr *buffer.Buffer, i interface{}) error {
writeInt64(wr, int64(*t))
case int8:
wr.Append([]byte{
byte(typeCodeByte),
byte(TypeCodeByte),
uint8(t),
})
case *int8:
wr.Append([]byte{
byte(typeCodeByte),
byte(TypeCodeByte),
uint8(*t),
})
case int16:
wr.AppendByte(byte(typeCodeShort))
wr.AppendByte(byte(TypeCodeShort))
wr.AppendUint16(uint16(t))
case *int16:
wr.AppendByte(byte(typeCodeShort))
wr.AppendByte(byte(TypeCodeShort))
wr.AppendUint16(uint16(*t))
case int32:
writeInt32(wr, t)
@ -100,9 +100,9 @@ func marshal(wr *buffer.Buffer, i interface{}) error {
case *string:
return writeString(wr, *t)
case []byte:
return writeBinary(wr, t)
return WriteBinary(wr, t)
case *[]byte:
return writeBinary(wr, *t)
return WriteBinary(wr, *t)
case map[interface{}]interface{}:
return writeMap(wr, t)
case *map[interface{}]interface{}:
@ -111,84 +111,84 @@ func marshal(wr *buffer.Buffer, i interface{}) error {
return writeMap(wr, t)
case *map[string]interface{}:
return writeMap(wr, *t)
case map[symbol]interface{}:
case map[Symbol]interface{}:
return writeMap(wr, t)
case *map[symbol]interface{}:
case *map[Symbol]interface{}:
return writeMap(wr, *t)
case unsettled:
case Unsettled:
return writeMap(wr, t)
case *unsettled:
case *Unsettled:
return writeMap(wr, *t)
case time.Time:
writeTimestamp(wr, t)
case *time.Time:
writeTimestamp(wr, *t)
case []int8:
return arrayInt8(t).marshal(wr)
return arrayInt8(t).Marshal(wr)
case *[]int8:
return arrayInt8(*t).marshal(wr)
return arrayInt8(*t).Marshal(wr)
case []uint16:
return arrayUint16(t).marshal(wr)
return arrayUint16(t).Marshal(wr)
case *[]uint16:
return arrayUint16(*t).marshal(wr)
return arrayUint16(*t).Marshal(wr)
case []int16:
return arrayInt16(t).marshal(wr)
return arrayInt16(t).Marshal(wr)
case *[]int16:
return arrayInt16(*t).marshal(wr)
return arrayInt16(*t).Marshal(wr)
case []uint32:
return arrayUint32(t).marshal(wr)
return arrayUint32(t).Marshal(wr)
case *[]uint32:
return arrayUint32(*t).marshal(wr)
return arrayUint32(*t).Marshal(wr)
case []int32:
return arrayInt32(t).marshal(wr)
return arrayInt32(t).Marshal(wr)
case *[]int32:
return arrayInt32(*t).marshal(wr)
return arrayInt32(*t).Marshal(wr)
case []uint64:
return arrayUint64(t).marshal(wr)
return arrayUint64(t).Marshal(wr)
case *[]uint64:
return arrayUint64(*t).marshal(wr)
return arrayUint64(*t).Marshal(wr)
case []int64:
return arrayInt64(t).marshal(wr)
return arrayInt64(t).Marshal(wr)
case *[]int64:
return arrayInt64(*t).marshal(wr)
return arrayInt64(*t).Marshal(wr)
case []float32:
return arrayFloat(t).marshal(wr)
return arrayFloat(t).Marshal(wr)
case *[]float32:
return arrayFloat(*t).marshal(wr)
return arrayFloat(*t).Marshal(wr)
case []float64:
return arrayDouble(t).marshal(wr)
return arrayDouble(t).Marshal(wr)
case *[]float64:
return arrayDouble(*t).marshal(wr)
return arrayDouble(*t).Marshal(wr)
case []bool:
return arrayBool(t).marshal(wr)
return arrayBool(t).Marshal(wr)
case *[]bool:
return arrayBool(*t).marshal(wr)
return arrayBool(*t).Marshal(wr)
case []string:
return arrayString(t).marshal(wr)
return arrayString(t).Marshal(wr)
case *[]string:
return arrayString(*t).marshal(wr)
case []symbol:
return arraySymbol(t).marshal(wr)
case *[]symbol:
return arraySymbol(*t).marshal(wr)
return arrayString(*t).Marshal(wr)
case []Symbol:
return arraySymbol(t).Marshal(wr)
case *[]Symbol:
return arraySymbol(*t).Marshal(wr)
case [][]byte:
return arrayBinary(t).marshal(wr)
return arrayBinary(t).Marshal(wr)
case *[][]byte:
return arrayBinary(*t).marshal(wr)
return arrayBinary(*t).Marshal(wr)
case []time.Time:
return arrayTimestamp(t).marshal(wr)
return arrayTimestamp(t).Marshal(wr)
case *[]time.Time:
return arrayTimestamp(*t).marshal(wr)
return arrayTimestamp(*t).Marshal(wr)
case []UUID:
return arrayUUID(t).marshal(wr)
return arrayUUID(t).Marshal(wr)
case *[]UUID:
return arrayUUID(*t).marshal(wr)
return arrayUUID(*t).Marshal(wr)
case []interface{}:
return list(t).marshal(wr)
return list(t).Marshal(wr)
case *[]interface{}:
return list(*t).marshal(wr)
return list(*t).Marshal(wr)
case marshaler:
return t.marshal(wr)
return t.Marshal(wr)
default:
return fmt.Errorf("marshal not implemented for %T", i)
}
@ -198,85 +198,85 @@ func marshal(wr *buffer.Buffer, i interface{}) error {
func writeInt32(wr *buffer.Buffer, n int32) {
if n < 128 && n >= -128 {
wr.Append([]byte{
byte(typeCodeSmallint),
byte(TypeCodeSmallint),
byte(n),
})
return
}
wr.AppendByte(byte(typeCodeInt))
wr.AppendByte(byte(TypeCodeInt))
wr.AppendUint32(uint32(n))
}
func writeInt64(wr *buffer.Buffer, n int64) {
if n < 128 && n >= -128 {
wr.Append([]byte{
byte(typeCodeSmalllong),
byte(TypeCodeSmalllong),
byte(n),
})
return
}
wr.AppendByte(byte(typeCodeLong))
wr.AppendByte(byte(TypeCodeLong))
wr.AppendUint64(uint64(n))
}
func writeUint32(wr *buffer.Buffer, n uint32) {
if n == 0 {
wr.AppendByte(byte(typeCodeUint0))
wr.AppendByte(byte(TypeCodeUint0))
return
}
if n < 256 {
wr.Append([]byte{
byte(typeCodeSmallUint),
byte(TypeCodeSmallUint),
byte(n),
})
return
}
wr.AppendByte(byte(typeCodeUint))
wr.AppendByte(byte(TypeCodeUint))
wr.AppendUint32(n)
}
func writeUint64(wr *buffer.Buffer, n uint64) {
if n == 0 {
wr.AppendByte(byte(typeCodeUlong0))
wr.AppendByte(byte(TypeCodeUlong0))
return
}
if n < 256 {
wr.Append([]byte{
byte(typeCodeSmallUlong),
byte(TypeCodeSmallUlong),
byte(n),
})
return
}
wr.AppendByte(byte(typeCodeUlong))
wr.AppendByte(byte(TypeCodeUlong))
wr.AppendUint64(n)
}
func writeFloat(wr *buffer.Buffer, f float32) {
wr.AppendByte(byte(typeCodeFloat))
wr.AppendByte(byte(TypeCodeFloat))
wr.AppendUint32(math.Float32bits(f))
}
func writeDouble(wr *buffer.Buffer, f float64) {
wr.AppendByte(byte(typeCodeDouble))
wr.AppendByte(byte(TypeCodeDouble))
wr.AppendUint64(math.Float64bits(f))
}
func writeTimestamp(wr *buffer.Buffer, t time.Time) {
wr.AppendByte(byte(typeCodeTimestamp))
wr.AppendByte(byte(TypeCodeTimestamp))
ms := t.UnixNano() / int64(time.Millisecond)
wr.AppendUint64(uint64(ms))
}
// marshalField is a field to be marshaled
type marshalField struct {
value interface{} // value to be marshaled, use pointers to avoid interface conversion overhead
omit bool // indicates that this field should be omitted (set to null)
type MarshalField struct {
Value interface{} // value to be marshaled, use pointers to avoid interface conversion overhead
Omit bool // indicates that this field should be omitted (set to null)
}
// marshalComposite is a helper for us in a composite's marshal() function.
@ -284,7 +284,7 @@ type marshalField struct {
// The returned bytes include the composite header and fields. Fields with
// omit set to true will be encoded as null or omitted altogether if there are
// no non-null fields after them.
func marshalComposite(wr *buffer.Buffer, code amqpType, fields []marshalField) error {
func MarshalComposite(wr *buffer.Buffer, code AMQPType, fields []MarshalField) error {
// lastSetIdx is the last index to have a non-omitted field.
// start at -1 as it's possible to have no fields in a composite
lastSetIdx := -1
@ -292,7 +292,7 @@ func marshalComposite(wr *buffer.Buffer, code amqpType, fields []marshalField) e
// marshal each field into it's index in rawFields,
// null fields are skipped, leaving the index nil.
for i, f := range fields {
if f.omit {
if f.Omit {
continue
}
lastSetIdx = i
@ -302,18 +302,18 @@ func marshalComposite(wr *buffer.Buffer, code amqpType, fields []marshalField) e
if lastSetIdx == -1 {
wr.Append([]byte{
0x0,
byte(typeCodeSmallUlong),
byte(TypeCodeSmallUlong),
byte(code),
byte(typeCodeList0),
byte(TypeCodeList0),
})
return nil
}
// write header
writeDescriptor(wr, code)
WriteDescriptor(wr, code)
// write fields
wr.AppendByte(byte(typeCodeList32))
wr.AppendByte(byte(TypeCodeList32))
// write temp size, replace later
sizeIdx := wr.Len()
@ -325,11 +325,11 @@ func marshalComposite(wr *buffer.Buffer, code amqpType, fields []marshalField) e
// write null to each index up to lastSetIdx
for _, f := range fields[:lastSetIdx+1] {
if f.omit {
wr.AppendByte(byte(typeCodeNull))
if f.Omit {
wr.AppendByte(byte(TypeCodeNull))
continue
}
err := marshal(wr, f.value)
err := Marshal(wr, f.Value)
if err != nil {
return err
}
@ -343,10 +343,10 @@ func marshalComposite(wr *buffer.Buffer, code amqpType, fields []marshalField) e
return nil
}
func writeDescriptor(wr *buffer.Buffer, code amqpType) {
func WriteDescriptor(wr *buffer.Buffer, code AMQPType) {
wr.Append([]byte{
0x0,
byte(typeCodeSmallUlong),
byte(TypeCodeSmallUlong),
byte(code),
})
}
@ -361,7 +361,7 @@ func writeString(wr *buffer.Buffer, str string) error {
// Str8
case l < 256:
wr.Append([]byte{
byte(typeCodeStr8),
byte(TypeCodeStr8),
byte(l),
})
wr.AppendString(str)
@ -369,7 +369,7 @@ func writeString(wr *buffer.Buffer, str string) error {
// Str32
case uint(l) < math.MaxUint32:
wr.AppendByte(byte(typeCodeStr32))
wr.AppendByte(byte(TypeCodeStr32))
wr.AppendUint32(uint32(l))
wr.AppendString(str)
return nil
@ -379,14 +379,14 @@ func writeString(wr *buffer.Buffer, str string) error {
}
}
func writeBinary(wr *buffer.Buffer, bin []byte) error {
func WriteBinary(wr *buffer.Buffer, bin []byte) error {
l := len(bin)
switch {
// List8
case l < 256:
wr.Append([]byte{
byte(typeCodeVbin8),
byte(TypeCodeVbin8),
byte(l),
})
wr.Append(bin)
@ -394,7 +394,7 @@ func writeBinary(wr *buffer.Buffer, bin []byte) error {
// List32
case uint(l) < math.MaxUint32:
wr.AppendByte(byte(typeCodeVbin32))
wr.AppendByte(byte(TypeCodeVbin32))
wr.AppendUint32(uint32(l))
wr.Append(bin)
return nil
@ -407,7 +407,7 @@ func writeBinary(wr *buffer.Buffer, bin []byte) error {
func writeMap(wr *buffer.Buffer, m interface{}) error {
startIdx := wr.Len()
wr.Append([]byte{
byte(typeCodeMap32), // type
byte(TypeCodeMap32), // type
0, 0, 0, 0, // size placeholder
0, 0, 0, 0, // length placeholder
})
@ -417,11 +417,11 @@ func writeMap(wr *buffer.Buffer, m interface{}) error {
case map[interface{}]interface{}:
pairs = len(m) * 2
for key, val := range m {
err := marshal(wr, key)
err := Marshal(wr, key)
if err != nil {
return err
}
err = marshal(wr, val)
err = Marshal(wr, val)
if err != nil {
return err
}
@ -433,43 +433,43 @@ func writeMap(wr *buffer.Buffer, m interface{}) error {
if err != nil {
return err
}
err = marshal(wr, val)
err = Marshal(wr, val)
if err != nil {
return err
}
}
case map[symbol]interface{}:
case map[Symbol]interface{}:
pairs = len(m) * 2
for key, val := range m {
err := key.marshal(wr)
err := key.Marshal(wr)
if err != nil {
return err
}
err = marshal(wr, val)
err = Marshal(wr, val)
if err != nil {
return err
}
}
case unsettled:
case Unsettled:
pairs = len(m) * 2
for key, val := range m {
err := writeString(wr, key)
if err != nil {
return err
}
err = marshal(wr, val)
err = Marshal(wr, val)
if err != nil {
return err
}
}
case filter:
case Filter:
pairs = len(m) * 2
for key, val := range m {
err := key.marshal(wr)
err := key.Marshal(wr)
if err != nil {
return err
}
err = val.marshal(wr)
err = val.Marshal(wr)
if err != nil {
return err
}
@ -479,12 +479,12 @@ func writeMap(wr *buffer.Buffer, m interface{}) error {
for key, val := range m {
switch key := key.(type) {
case string:
err := symbol(key).marshal(wr)
err := Symbol(key).Marshal(wr)
if err != nil {
return err
}
case symbol:
err := key.marshal(wr)
case Symbol:
err := key.Marshal(wr)
if err != nil {
return err
}
@ -496,7 +496,7 @@ func writeMap(wr *buffer.Buffer, m interface{}) error {
return fmt.Errorf("unsupported Annotations key type %T", key)
}
err := marshal(wr, val)
err := Marshal(wr, val)
if err != nil {
return err
}
@ -526,26 +526,26 @@ const (
array32TLSize = 5
)
func writeArrayHeader(wr *buffer.Buffer, length, typeSize int, type_ amqpType) {
func writeArrayHeader(wr *buffer.Buffer, length, typeSize int, type_ AMQPType) {
size := length * typeSize
// array type
if size+array8TLSize <= math.MaxUint8 {
wr.Append([]byte{
byte(typeCodeArray8), // type
byte(TypeCodeArray8), // type
byte(size + array8TLSize), // size
byte(length), // length
byte(type_), // element type
})
} else {
wr.AppendByte(byte(typeCodeArray32)) //type
wr.AppendByte(byte(TypeCodeArray32)) //type
wr.AppendUint32(uint32(size + array32TLSize)) // size
wr.AppendUint32(uint32(length)) // length
wr.AppendByte(byte(type_)) // element type
}
}
func writeVariableArrayHeader(wr *buffer.Buffer, length, elementsSizeTotal int, type_ amqpType) {
func writeVariableArrayHeader(wr *buffer.Buffer, length, elementsSizeTotal int, type_ AMQPType) {
// 0xA_ == 1, 0xB_ == 4
// http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-types-v1.0-os.html#doc-idp82960
elementTypeSize := 1
@ -556,13 +556,13 @@ func writeVariableArrayHeader(wr *buffer.Buffer, length, elementsSizeTotal int,
size := elementsSizeTotal + (length * elementTypeSize) // size excluding array length
if size+array8TLSize <= math.MaxUint8 {
wr.Append([]byte{
byte(typeCodeArray8), // type
byte(TypeCodeArray8), // type
byte(size + array8TLSize), // size
byte(length), // length
byte(type_), // element type
})
} else {
wr.AppendByte(byte(typeCodeArray32)) // type
wr.AppendByte(byte(TypeCodeArray32)) // type
wr.AppendUint32(uint32(size + array32TLSize)) // size
wr.AppendUint32(uint32(length)) // length
wr.AppendByte(byte(type_)) // element type

Просмотреть файл

@ -0,0 +1,157 @@
package encoding
import (
"io/ioutil"
"os"
"path/filepath"
"strconv"
"testing"
"time"
"github.com/Azure/go-amqp/internal/buffer"
)
func fuzzUnmarshal(data []byte) int {
types := []interface{}{
new(Error),
new(*Error),
new(StateReceived),
new(*StateReceived),
new(StateAccepted),
new(*StateAccepted),
new(StateRejected),
new(*StateRejected),
new(StateReleased),
new(*StateReleased),
new(StateModified),
new(*StateModified),
new(mapAnyAny),
new(*mapAnyAny),
new(mapStringAny),
new(*mapStringAny),
new(mapSymbolAny),
new(*mapSymbolAny),
new(Unsettled),
new(*Unsettled),
new(Milliseconds),
new(*Milliseconds),
new(bool),
new(*bool),
new(int8),
new(*int8),
new(int16),
new(*int16),
new(int32),
new(*int32),
new(int64),
new(*int64),
new(uint8),
new(*uint8),
new(uint16),
new(*uint16),
new(uint32),
new(*uint32),
new(uint64),
new(*uint64),
new(time.Time),
new(*time.Time),
new(time.Duration),
new(*time.Duration),
new(Symbol),
new(*Symbol),
new([]byte),
new(*[]byte),
new([]string),
new(*[]string),
new([]Symbol),
new(*[]Symbol),
new(map[interface{}]interface{}),
new(*map[interface{}]interface{}),
new(map[string]interface{}),
new(*map[string]interface{}),
new(map[Symbol]interface{}),
new(*map[Symbol]interface{}),
new(interface{}),
new(*interface{}),
new(ErrorCondition),
new(*ErrorCondition),
new(UUID),
new(*UUID),
}
for _, t := range types {
_ = Unmarshal(buffer.New(data), t)
_, _ = ReadAny(buffer.New(data))
}
return 0
}
func TestFuzzMarshalCrashers(t *testing.T) {
tests := []string{
0: "\xc1\x000\xa0\x00S0",
1: "\xf0S\x13\xc0\x12\v@`@@`\v@```@@@",
2: "\xe000\xb0",
3: "\xc1\x000\xe000R",
4: "\xe000S",
5: "\x00\xe000R",
6: "\xe000\x83",
7: "\x00\x00\xe000S",
8: "\xe000R",
9: "\x00\xe000S",
10: "\xc1\x000\xe000S",
11: "\xc1\x000\x00\xe000S",
12: "\xc1\x000\x00\xe000R",
13: "\x00\x00\xe000R",
14: "\xe000\xb1",
15: "\xc1\x00%\xd0\x00\x00\x00M\xe2\x00\x00\x01\x00S\x1d\xd0\x00\x00\x00A" +
"\x00\x00\x00\x03\xa3\x10amqp:link:stol" +
"en\xa1\x0foo\xb1\xdefoo descript" +
"ion\xc1\x18\x04\xa1\x05other\xa1\x04info\xa1" +
"\x03andq\x00\x00\x03k",
16: "\xd1\x00\x00\x00M\x00S\x1d\xd0\x00S\x1d\xd0\x00\x00\x00A\x00\x80\x00" +
"\x03\xa3\x10amqp:link:stolen\xa1" +
"\x19foo description\xc1\x18\x04\xa1" +
"\x05other\xa1\x04info\xa1\x03andU\x00\x00" +
"\x03k",
17: "\xf0\x00\x00\x00\x01@\x00TRUE\x00",
18: "\xf0\x00\x00\x00\x00\x10RTRT",
19: "\x00p\x00inp\xf0\x00\x00\x00\x01p\x00inp",
}
for i, tt := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
fuzzUnmarshal([]byte(tt))
})
}
}
func testDirFiles(t *testing.T, dir string) []string {
finfos, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatal(err)
}
var fullpaths []string
for _, finfo := range finfos {
fullpaths = append(fullpaths, filepath.Join(dir, finfo.Name()))
}
return fullpaths
}
func TestFuzzMarshalCorpus(t *testing.T) {
if os.Getenv("TEST_CORPUS") == "" {
t.Skip("set TEST_CORPUS to enable")
}
for _, path := range testDirFiles(t, "testdata/fuzz/marshal/corpus") {
t.Run(filepath.Base(path), func(t *testing.T) {
data, err := ioutil.ReadFile(path)
if err != nil {
t.Fatal(err)
}
fuzzUnmarshal(data)
})
}
}

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше