From f82b1dd7c384e0295530f2ded53c0938f7b2fc9b Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 10 Feb 2021 02:50:44 +0000 Subject: [PATCH] Prevent adding nil label to .AddedLabels or .RemovedLabels (#14623) * Prevent adding nil label to .AddedLabels or .RemovedLabels There are possibly a few old databases out there with malmigrated data that can cause panics with empty labels being migrated. This PR adds a few tests to prevent nil labels being added. Fix #14466 Signed-off-by: Andrew Thornton * Add doctor command to remove the broken label comments Signed-off-by: Andrew Thornton Co-authored-by: 6543 <6543@obermui.de> --- models/consistency.go | 10 ++++++++++ modules/doctor/dbconsistency.go | 18 ++++++++++++++++++ modules/templates/helper.go | 4 ++++ routers/repo/issue.go | 12 +++++++----- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/models/consistency.go b/models/consistency.go index f689261a5..aa46e787f 100644 --- a/models/consistency.go +++ b/models/consistency.go @@ -305,3 +305,13 @@ func CountWrongUserType() (int64, error) { func FixWrongUserType() (int64, error) { return x.Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&User{Type: 1}) } + +// CountCommentTypeLabelWithEmptyLabel count label comments with empty label +func CountCommentTypeLabelWithEmptyLabel() (int64, error) { + return x.Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment)) +} + +// FixCommentTypeLabelWithEmptyLabel count label comments with empty label +func FixCommentTypeLabelWithEmptyLabel() (int64, error) { + return x.Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment)) +} diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index f09aaa6d1..942a45cb3 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -111,6 +111,24 @@ func checkDBConsistency(logger log.Logger, autofix bool) error { } } + // find label comments with empty labels + count, err = models.CountCommentTypeLabelWithEmptyLabel() + if err != nil { + logger.Critical("Error: %v whilst counting label comments with empty labels") + return err + } + if count > 0 { + if autofix { + updatedCount, err := models.FixCommentTypeLabelWithEmptyLabel() + if err != nil { + logger.Critical("Error: %v whilst removing label comments with empty labels") + return err + } + logger.Info("%d label comments with empty labels removed", updatedCount) + } else { + logger.Warn("%d label comments with empty labels", count) + } + } // TODO: function to recalc all counters return nil diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 4e767ad44..987a6ad98 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -371,6 +371,10 @@ func NewFuncMap() []template.FuncMap { "RenderLabels": func(labels []*models.Label) template.HTML { html := `` for _, label := range labels { + // Protect against nil value in labels - shouldn't happen but would cause a panic if so + if label == nil { + continue + } html += fmt.Sprintf("
%s
", label.ForegroundColor(), label.Color, RenderEmoji(label.Name)) } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 3bc20839a..1f57f2e9c 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -2464,7 +2464,7 @@ func combineLabelComments(issue *models.Issue) { if i == 0 || cur.Type != models.CommentTypeLabel || (prev != nil && prev.PosterID != cur.PosterID) || (prev != nil && cur.CreatedUnix-prev.CreatedUnix >= 60) { - if cur.Type == models.CommentTypeLabel { + if cur.Type == models.CommentTypeLabel && cur.Label != nil { if cur.Content != "1" { cur.RemovedLabels = append(cur.RemovedLabels, cur.Label) } else { @@ -2474,10 +2474,12 @@ func combineLabelComments(issue *models.Issue) { continue } - if cur.Content != "1" { - prev.RemovedLabels = append(prev.RemovedLabels, cur.Label) - } else { - prev.AddedLabels = append(prev.AddedLabels, cur.Label) + if cur.Label != nil { + if cur.Content != "1" { + prev.RemovedLabels = append(prev.RemovedLabels, cur.Label) + } else { + prev.AddedLabels = append(prev.AddedLabels, cur.Label) + } } prev.CreatedUnix = cur.CreatedUnix issue.Comments = append(issue.Comments[:i], issue.Comments[i+1:]...)