Explorar el Código

Fix crash when warning offline user

When a warned screenname is offline ras would attempt to send an empty SNAC,
which caused a crash when marshalling the nil value. Fix by sending a proper
error message, and also detect the nil value when marshalling so we don't crash
on future empty snacs.

Closes #38
Josh Knight hace 2 años
padre
commit
bf2613fa64
Se han modificado 3 ficheros con 20 adiciones y 1 borrados
  1. 10 1
      foodgroup/icbm.go
  2. 4 0
      wire/encode.go
  3. 6 0
      wire/encode_test.go

+ 10 - 1
foodgroup/icbm.go

@@ -213,7 +213,16 @@ func (s ICBMService) EvilRequest(ctx context.Context, sess *state.Session, inFra
 
 	recipSess := s.messageRelayer.RetrieveByScreenName(inBody.ScreenName)
 	if recipSess == nil {
-		return wire.SNACMessage{}, nil
+		return wire.SNACMessage{
+			Frame: wire.SNACFrame{
+				FoodGroup: wire.ICBM,
+				SubGroup:  wire.ICBMErr,
+				RequestID: inFrame.RequestID,
+			},
+			Body: wire.SNACError{
+				Code: wire.ErrorCodeNotLoggedOn,
+			},
+		}, nil
 	}
 
 	increase := evilDelta

+ 4 - 0
wire/encode.go

@@ -10,12 +10,16 @@ import (
 )
 
 var ErrMarshalFailure = errors.New("failed to marshal")
+var ErrMarshalFailureNilSNAC = errors.New("attempting to marshal a nil SNAC")
 
 func Marshal(v any, w io.Writer) error {
 	return marshal(reflect.TypeOf(v), reflect.ValueOf(v), "", w)
 }
 
 func marshal(t reflect.Type, v reflect.Value, tag reflect.StructTag, w io.Writer) error {
+	if t == nil {
+		return ErrMarshalFailureNilSNAC
+	}
 	switch t.Kind() {
 	case reflect.Struct:
 		for i := 0; i < t.NumField(); i++ {

+ 6 - 0
wire/encode_test.go

@@ -323,6 +323,12 @@ func TestMarshal(t *testing.T) {
 			},
 			wantErr: ErrMarshalFailure,
 		},
+		{
+			name:    "empty snac",
+			w:       &bytes.Buffer{},
+			given:   nil,
+			wantErr: ErrMarshalFailureNilSNAC,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {