Fix SIGSEGV in xmpp_component (#126)

* SIGSEGV in xmpp_component example with Prosody #126
This commit is contained in:
remicorniere 2019-11-22 15:07:40 +01:00 committed by Jérôme Sautret
parent 6aa1e668ee
commit 7d89353156
4 changed files with 47 additions and 5 deletions

View File

@ -7,9 +7,8 @@ import (
"encoding/xml" "encoding/xml"
"errors" "errors"
"fmt" "fmt"
"io"
"gosrc.io/xmpp/stanza" "gosrc.io/xmpp/stanza"
"io"
) )
type ComponentOptions struct { type ComponentOptions struct {
@ -50,7 +49,6 @@ type Component struct {
// read / write // read / write
socketProxy io.ReadWriter // TODO socketProxy io.ReadWriter // TODO
decoder *xml.Decoder
} }
func NewComponent(opts ComponentOptions, r *Router) (*Component, error) { func NewComponent(opts ComponentOptions, r *Router) (*Component, error) {
@ -90,7 +88,7 @@ func (c *Component) Resume(sm SMState) error {
} }
// Check server response for authentication // Check server response for authentication
val, err := stanza.NextPacket(c.decoder) val, err := stanza.NextPacket(c.transport.GetDecoder())
if err != nil { if err != nil {
c.updateState(StatePermanentError) c.updateState(StatePermanentError)
return NewConnError(err, true) return NewConnError(err, true)
@ -125,7 +123,7 @@ func (c *Component) SetHandler(handler EventHandler) {
// Receiver Go routine receiver // Receiver Go routine receiver
func (c *Component) recv() (err error) { func (c *Component) recv() (err error) {
for { for {
val, err := stanza.NextPacket(c.decoder) val, err := stanza.NextPacket(c.transport.GetDecoder())
if err != nil { if err != nil {
c.updateState(StateDisconnected) c.updateState(StateDisconnected)
return err return err

View File

@ -1,9 +1,13 @@
package xmpp package xmpp
import ( import (
"fmt"
"testing" "testing"
) )
const testComponentDomain = "localhost"
const testComponentPort = "15222"
func TestHandshake(t *testing.T) { func TestHandshake(t *testing.T) {
opts := ComponentOptions{ opts := ComponentOptions{
Domain: "test.localhost", Domain: "test.localhost",
@ -30,3 +34,41 @@ func TestGenerateHandshake(t *testing.T) {
func TestStreamManager(t *testing.T) { func TestStreamManager(t *testing.T) {
NewStreamManager(&Component{}, nil) 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.")
}
}

View File

@ -20,6 +20,7 @@ const pingTimeout = time.Duration(5) * time.Second
var ServerDoesNotSupportXmppOverWebsocket = errors.New("The websocket server does not support the xmpp subprotocol") 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 { type WebsocketTransport struct {
Config TransportConfiguration Config TransportConfiguration
decoder *xml.Decoder decoder *xml.Decoder

View File

@ -14,6 +14,7 @@ import (
) )
// XMPPTransport implements the XMPP native TCP transport // XMPPTransport implements the XMPP native TCP transport
// The decoder is expected to be initialized after connecting to a server.
type XMPPTransport struct { type XMPPTransport struct {
openStatement string openStatement string
Config TransportConfiguration Config TransportConfiguration