mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-26 06:16:56 +09:00
getPullRequestInfo and getIssuesInfo indexed into the last element of an empty Assignees slice when Action was HookIssueAssigned, causing a panic under a race where the assignee list is empty by the time the webhook payload is built. Fixes https://github.com/go-gitea/gitea/issues/39826 Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
55 lines
1.6 KiB
Go
55 lines
1.6 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package notify
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
issues_model "gitea.dev/models/issues"
|
|
user_model "gitea.dev/models/user"
|
|
"gitea.dev/modules/log"
|
|
"gitea.dev/modules/test"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type panicNotifier struct {
|
|
NullNotifier
|
|
panicValue any
|
|
called bool
|
|
}
|
|
|
|
func (n *panicNotifier) NewIssue(context.Context, *issues_model.Issue, []*user_model.User) {
|
|
n.called = true
|
|
panic(n.panicValue)
|
|
}
|
|
|
|
func TestNotificationPanicRecovery(t *testing.T) {
|
|
notifier := &panicNotifier{}
|
|
defer test.MockVariableValue(¬ifiers, []Notifier{notifier})()
|
|
|
|
for _, panicValue := range []any{"notification panic", errors.New("notification error"), nil} {
|
|
notifier.panicValue = panicValue
|
|
notifier.called = false
|
|
assert.NotPanics(t, func() { NewIssue(t.Context(), nil, nil) })
|
|
assert.True(t, notifier.called)
|
|
}
|
|
|
|
checker, cleanup := test.NewLogChecker(log.DEFAULT)
|
|
defer cleanup()
|
|
checker.Filter("PANIC while notifying: notification panic", "notify_test.go", "notify.go").StopMark("notification recovery complete")
|
|
notifier.panicValue = "notification panic"
|
|
assert.NotPanics(t, func() { NewIssue(t.Context(), nil, nil) })
|
|
log.Info("notification recovery complete")
|
|
filtered, stopped := checker.Check(time.Second)
|
|
assert.True(t, stopped)
|
|
assert.Equal(t, []bool{true, true, true}, filtered)
|
|
|
|
assert.NotPanics(t, func() { CreateIssueComment(t.Context(), nil, nil, nil, nil, nil) })
|
|
assert.NotPanics(t, func() { NewPullRequest(t.Context(), nil, nil) })
|
|
}
|