Skip to content

Commit 48898e5

Browse files
ethantkoeniglunny
authored andcommitted
Fix PR nil-dereference bug (#2195)
* Fix PR nil-dereference bug * Revert to original error format
1 parent dde0052 commit 48898e5

File tree

2 files changed

+91
-7
lines changed

2 files changed

+91
-7
lines changed

models/issue.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,19 @@ func (issue *Issue) loadAssignee(e Engine) (err error) {
148148
return
149149
}
150150

151+
func (issue *Issue) loadPullRequest(e Engine) (err error) {
152+
if issue.IsPull && issue.PullRequest == nil {
153+
issue.PullRequest, err = getPullRequestByIssueID(e, issue.ID)
154+
if err != nil {
155+
if IsErrPullRequestNotExist(err) {
156+
return err
157+
}
158+
return fmt.Errorf("getPullRequestByIssueID [%d]: %v", issue.ID, err)
159+
}
160+
}
161+
return nil
162+
}
163+
151164
func (issue *Issue) loadAttributes(e Engine) (err error) {
152165
if err = issue.loadRepo(e); err != nil {
153166
return
@@ -172,12 +185,9 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
172185
return
173186
}
174187

175-
if issue.IsPull && issue.PullRequest == nil {
188+
if err = issue.loadPullRequest(e); err != nil && !IsErrPullRequestNotExist(err) {
176189
// It is possible pull request is not yet created.
177-
issue.PullRequest, err = getPullRequestByIssueID(e, issue.ID)
178-
if err != nil && !IsErrPullRequestNotExist(err) {
179-
return fmt.Errorf("getPullRequestByIssueID [%d]: %v", issue.ID, err)
180-
}
190+
return err
181191
}
182192

183193
if issue.Attachments == nil {
@@ -321,8 +331,15 @@ func (issue *Issue) HasLabel(labelID int64) bool {
321331
func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
322332
var err error
323333
if issue.IsPull {
324-
err = issue.PullRequest.LoadIssue()
325-
if err != nil {
334+
if err = issue.loadRepo(x); err != nil {
335+
log.Error(4, "loadRepo: %v", err)
336+
return
337+
}
338+
if err = issue.loadPullRequest(x); err != nil {
339+
log.Error(4, "loadPullRequest: %v", err)
340+
return
341+
}
342+
if err = issue.PullRequest.LoadIssue(); err != nil {
326343
log.Error(4, "LoadIssue: %v", err)
327344
return
328345
}
@@ -430,6 +447,8 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
430447

431448
if err := issue.loadRepo(sess); err != nil {
432449
return err
450+
} else if err = issue.loadPullRequest(sess); err != nil {
451+
return err
433452
}
434453

435454
if has, err := hasAccess(sess, doer.ID, issue.Repo, AccessModeWrite); err != nil {

models/issue_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,68 @@ func TestGetParticipantsByIssueID(t *testing.T) {
8181
// Users 3 and 5 made actual comments (see fixtures/comment.yml)
8282
checkParticipants(1, []int{3, 5})
8383
}
84+
85+
func TestIssue_AddLabel(t *testing.T) {
86+
var tests = []struct {
87+
issueID int64
88+
labelID int64
89+
doerID int64
90+
}{
91+
{1, 2, 2}, // non-pull-request, not-already-added label
92+
{1, 1, 2}, // non-pull-request, already-added label
93+
{2, 2, 2}, // pull-request, not-already-added label
94+
{2, 1, 2}, // pull-request, already-added label
95+
}
96+
for _, test := range tests {
97+
assert.NoError(t, PrepareTestDatabase())
98+
issue := AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue)
99+
label := AssertExistsAndLoadBean(t, &Label{ID: test.labelID}).(*Label)
100+
doer := AssertExistsAndLoadBean(t, &User{ID: test.doerID}).(*User)
101+
assert.NoError(t, issue.AddLabel(doer, label))
102+
AssertExistsAndLoadBean(t, &IssueLabel{IssueID: test.issueID, LabelID: test.labelID})
103+
}
104+
}
105+
106+
func TestIssue_AddLabels(t *testing.T) {
107+
var tests = []struct {
108+
issueID int64
109+
labelIDs []int64
110+
doerID int64
111+
}{
112+
{1, []int64{1, 2}, 2}, // non-pull-request
113+
{1, []int64{}, 2}, // non-pull-request, empty
114+
{2, []int64{1, 2}, 2}, // pull-request
115+
{2, []int64{}, 1}, // pull-request, empty
116+
}
117+
for _, test := range tests {
118+
assert.NoError(t, PrepareTestDatabase())
119+
issue := AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue)
120+
labels := make([]*Label, len(test.labelIDs))
121+
for i, labelID := range test.labelIDs {
122+
labels[i] = AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label)
123+
}
124+
doer := AssertExistsAndLoadBean(t, &User{ID: test.doerID}).(*User)
125+
assert.NoError(t, issue.AddLabels(doer, labels))
126+
for _, labelID := range test.labelIDs {
127+
AssertExistsAndLoadBean(t, &IssueLabel{IssueID: test.issueID, LabelID: labelID})
128+
}
129+
}
130+
}
131+
132+
func TestIssue_ClearLabels(t *testing.T) {
133+
var tests = []struct {
134+
issueID int64
135+
doerID int64
136+
}{
137+
{1, 2}, // non-pull-request, has labels
138+
{2, 2}, // pull-request, has labels
139+
{3, 2}, // pull-request, has no labels
140+
}
141+
for _, test := range tests {
142+
assert.NoError(t, PrepareTestDatabase())
143+
issue := AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue)
144+
doer := AssertExistsAndLoadBean(t, &User{ID: test.doerID}).(*User)
145+
assert.NoError(t, issue.ClearLabels(doer))
146+
AssertNotExistsBean(t, &IssueLabel{IssueID: test.issueID})
147+
}
148+
}

0 commit comments

Comments
 (0)