From 7d89353156577787bb996397efd9eb92c12f730e Mon Sep 17 00:00:00 2001 From: remicorniere Date: Fri, 22 Nov 2019 15:07:40 +0100 Subject: [PATCH] Fix SIGSEGV in xmpp_component (#126) * SIGSEGV in xmpp_component example with Prosody #126 --- component.go | 8 +++----- component_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ websocket_transport.go | 1 + xmpp_transport.go | 1 + 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/component.go b/component.go index d3c890e..cb468db 100644 --- a/component.go +++ b/component.go @@ -7,9 +7,8 @@ import ( "encoding/xml" "errors" "fmt" - "io" - "gosrc.io/xmpp/stanza" + "io" ) type ComponentOptions struct { @@ -50,7 +49,6 @@ type Component struct { // read / write socketProxy io.ReadWriter // TODO - decoder *xml.Decoder } func NewComponent(opts ComponentOptions, r *Router) (*Component, error) { @@ -90,7 +88,7 @@ func (c *Component) Resume(sm SMState) error { } // Check server response for authentication - val, err := stanza.NextPacket(c.decoder) + val, err := stanza.NextPacket(c.transport.GetDecoder()) if err != nil { c.updateState(StatePermanentError) return NewConnError(err, true) @@ -125,7 +123,7 @@ func (c *Component) SetHandler(handler EventHandler) { // Receiver Go routine receiver func (c *Component) recv() (err error) { for { - val, err := stanza.NextPacket(c.decoder) + val, err := stanza.NextPacket(c.transport.GetDecoder()) if err != nil { c.updateState(StateDisconnected) return err diff --git a/component_test.go b/component_test.go index 5fbe45b..8938769 100644 --- a/component_test.go +++ b/component_test.go @@ -1,9 +1,13 @@ package xmpp import ( + "fmt" "testing" ) +const testComponentDomain = "localhost" +const testComponentPort = "15222" + func TestHandshake(t *testing.T) { opts := ComponentOptions{ Domain: "test.localhost", @@ -30,3 +34,41 @@ func TestGenerateHandshake(t *testing.T) { func TestStreamManager(t *testing.T) { NewStreamManager(&Component{}, nil) } + +// Tests that the decoder is properly initialized when connecting a component to a server. +// The decoder is expected to be built after a valid connection +// Based on the xmpp_component example. +func TestDecoder(t *testing.T) { + testComponentAddess := fmt.Sprintf("%s:%s", testComponentDomain, testComponentPort) + mock := ServerMock{} + mock.Start(t, testComponentAddess, handlerConnectSuccess) + + opts := ComponentOptions{ + TransportConfiguration: TransportConfiguration{ + Address: testComponentAddess, + Domain: "localhost", + }, + Domain: testComponentDomain, + Secret: "mypass", + Name: "Test Component", + Category: "gateway", + Type: "service", + } + router := NewRouter() + c, err := NewComponent(opts, router) + if err != nil { + t.Errorf("%+v", err) + } + c.transport, err = NewComponentTransport(c.ComponentOptions.TransportConfiguration) + if err != nil { + t.Errorf("%+v", err) + } + _, err = c.transport.Connect() + if err != nil { + t.Errorf("%+v", err) + } + if c.transport.GetDecoder() == nil { + t.Errorf("Failed to initialize decoder. Decoder is nil.") + } + +} diff --git a/websocket_transport.go b/websocket_transport.go index d7b62c4..69c0183 100644 --- a/websocket_transport.go +++ b/websocket_transport.go @@ -20,6 +20,7 @@ const pingTimeout = time.Duration(5) * time.Second var ServerDoesNotSupportXmppOverWebsocket = errors.New("The websocket server does not support the xmpp subprotocol") +// The decoder is expected to be initialized after connecting to a server. type WebsocketTransport struct { Config TransportConfiguration decoder *xml.Decoder diff --git a/xmpp_transport.go b/xmpp_transport.go index 99e0f56..34b0d3e 100644 --- a/xmpp_transport.go +++ b/xmpp_transport.go @@ -14,6 +14,7 @@ import ( ) // XMPPTransport implements the XMPP native TCP transport +// The decoder is expected to be initialized after connecting to a server. type XMPPTransport struct { openStatement string Config TransportConfiguration