Initialize context actions with their client
This commit is contained in:
committed by
Brandon McGinty
parent
12dfa562d2
commit
f67cc657eb
@@ -28,7 +28,7 @@ Priority 0: security and crashers
|
|||||||
ensure channel close/send are serialized. Do not rely on the TCP read
|
ensure channel close/send are serialized. Do not rely on the TCP read
|
||||||
routine being serialized with UDP.
|
routine being serialized with UDP.
|
||||||
|
|
||||||
3. Context actions panic on receipt and on trigger
|
[x] 3. Context actions panic on receipt and on trigger
|
||||||
Files: gumble/gumble/client.go, gumble/gumble/handlers.go,
|
Files: gumble/gumble/client.go, gumble/gumble/handlers.go,
|
||||||
gumble/gumble/contextaction.go
|
gumble/gumble/contextaction.go
|
||||||
Client.ContextActions is never initialized, so the first
|
Client.ContextActions is never initialized, so the first
|
||||||
|
|||||||
@@ -118,10 +118,11 @@ func DialWithDialer(dialer *net.Dialer, config *Config, tlsConfig *tls.Config) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
client := &Client{
|
client := &Client{
|
||||||
Conn: NewConn(conn),
|
Conn: NewConn(conn),
|
||||||
Config: config,
|
Config: config,
|
||||||
Users: make(Users),
|
Users: make(Users),
|
||||||
Channels: make(Channels),
|
Channels: make(Channels),
|
||||||
|
ContextActions: make(ContextActions),
|
||||||
|
|
||||||
permissions: make(map[uint32]*Permission),
|
permissions: make(map[uint32]*Permission),
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package gumble
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.stormux.org/storm/barnard/gumble/gumble/MumbleProto"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regression: server context-action adds wrote to a nil map and the resulting
|
||||||
|
// action had no owning client, so Trigger panicked.
|
||||||
|
func TestContextActionAddAndTrigger(t *testing.T) {
|
||||||
|
clientConn, serverConn := net.Pipe()
|
||||||
|
defer serverConn.Close()
|
||||||
|
c := &Client{Config: NewConfig(), Users: make(Users), Channels: make(Channels), ContextActions: make(ContextActions)}
|
||||||
|
c.Conn = NewConn(clientConn)
|
||||||
|
action, operation := "test", MumbleProto.ContextActionModify_Add
|
||||||
|
data, err := proto.Marshal(&MumbleProto.ContextActionModify{Action: &action, Operation: &operation})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := c.handleContextActionModify(data); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
added := c.ContextActions[action]
|
||||||
|
if added == nil || added.client != c {
|
||||||
|
t.Fatal("action was not initialized with its client")
|
||||||
|
}
|
||||||
|
written := make(chan error, 1)
|
||||||
|
go func() { _, _, err := NewConn(serverConn).ReadPacket(); written <- err }()
|
||||||
|
added.Trigger()
|
||||||
|
if err := <-written; err != nil {
|
||||||
|
t.Fatalf("trigger did not write: %v", err)
|
||||||
|
}
|
||||||
|
remove := MumbleProto.ContextActionModify_Remove
|
||||||
|
data, _ = proto.Marshal(&MumbleProto.ContextActionModify{Action: &action, Operation: &remove})
|
||||||
|
if err := c.handleContextActionModify(data); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if c.ContextActions[action] != nil {
|
||||||
|
t.Fatal("action was not removed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regression: the documented bit layout disagreed with SemanticVersion.
|
||||||
|
func TestSemanticVersionKnownLayout(t *testing.T) {
|
||||||
|
major, minor, patch := (&Version{Version: 1<<16 | 5<<8 | 2}).SemanticVersion()
|
||||||
|
if major != 1 || minor != 5 || patch != 2 {
|
||||||
|
t.Fatalf("got %d.%d.%d", major, minor, patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,10 @@ package gumble
|
|||||||
// ContextActions is a map of ContextActions.
|
// ContextActions is a map of ContextActions.
|
||||||
type ContextActions map[string]*ContextAction
|
type ContextActions map[string]*ContextAction
|
||||||
|
|
||||||
func (c ContextActions) create(action string) *ContextAction {
|
func (c ContextActions) create(client *Client, action string) *ContextAction {
|
||||||
contextAction := &ContextAction{
|
contextAction := &ContextAction{
|
||||||
Name: action,
|
Name: action,
|
||||||
|
client: client,
|
||||||
}
|
}
|
||||||
c[action] = contextAction
|
c[action] = contextAction
|
||||||
return contextAction
|
return contextAction
|
||||||
|
|||||||
@@ -1029,7 +1029,7 @@ func (c *Client) handleContextActionModify(buffer []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
event.Type = ContextActionAdd
|
event.Type = ContextActionAdd
|
||||||
contextAction := c.ContextActions.create(*packet.Action)
|
contextAction := c.ContextActions.create(c, *packet.Action)
|
||||||
if packet.Text != nil {
|
if packet.Text != nil {
|
||||||
contextAction.Label = *packet.Text
|
contextAction.Label = *packet.Text
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user