fix: prevent panic when GitLab release has more links than sources (#36295)

The code incorrectly assumed rel.Assets.Links and rel.Assets.Sources
arrays have equal length. This causes index out of bounds panic when
migrating GitLab releases with more links than sources, which is common
with GoReleaser-generated releases.

Fixes #36292

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Joakim Olsson
2026-01-05 14:48:12 +01:00
committed by GitHub
parent 426bb491c0
commit 1ee7f8e966
4 changed files with 7 additions and 7 deletions
+6 -3
View File
@@ -10,9 +10,12 @@ import (
// ReleaseAsset represents a release asset // ReleaseAsset represents a release asset
type ReleaseAsset struct { type ReleaseAsset struct {
ID int64 ID int64
Name string Name string
ContentType *string `yaml:"content_type"`
// There was a field "ContentType (content_type)" because Some forges can provide that for assets,
// but we don't need it when migrating, so the field is omitted here.
Size *int Size *int
DownloadCount *int `yaml:"download_count"` DownloadCount *int `yaml:"download_count"`
Created time.Time Created time.Time
-1
View File
@@ -329,7 +329,6 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith
r.Assets = append(r.Assets, &base.ReleaseAsset{ r.Assets = append(r.Assets, &base.ReleaseAsset{
ID: asset.GetID(), ID: asset.GetID(),
Name: asset.GetName(), Name: asset.GetName(),
ContentType: asset.ContentType,
Size: asset.Size, Size: asset.Size,
DownloadCount: asset.DownloadCount, DownloadCount: asset.DownloadCount,
Created: asset.CreatedAt.Time, Created: asset.CreatedAt.Time,
+1 -2
View File
@@ -316,12 +316,11 @@ func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab
httpClient := NewMigrationHTTPClient() httpClient := NewMigrationHTTPClient()
for k, asset := range rel.Assets.Links { for _, asset := range rel.Assets.Links {
assetID := asset.ID // Don't optimize this, for closure we need a local variable assetID := asset.ID // Don't optimize this, for closure we need a local variable
r.Assets = append(r.Assets, &base.ReleaseAsset{ r.Assets = append(r.Assets, &base.ReleaseAsset{
ID: int64(asset.ID), ID: int64(asset.ID),
Name: asset.Name, Name: asset.Name,
ContentType: &rel.Assets.Sources[k].Format,
Size: &zero, Size: &zero,
DownloadCount: &zero, DownloadCount: &zero,
DownloadFunc: func() (io.ReadCloser, error) { DownloadFunc: func() (io.ReadCloser, error) {
-1
View File
@@ -171,7 +171,6 @@ func assertReactionsEqual(t *testing.T, expected, actual []*base.Reaction) {
func assertReleaseAssetEqual(t *testing.T, expected, actual *base.ReleaseAsset) { func assertReleaseAssetEqual(t *testing.T, expected, actual *base.ReleaseAsset) {
assert.Equal(t, expected.ID, actual.ID) assert.Equal(t, expected.ID, actual.ID)
assert.Equal(t, expected.Name, actual.Name) assert.Equal(t, expected.Name, actual.Name)
assert.Equal(t, expected.ContentType, actual.ContentType)
assert.Equal(t, expected.Size, actual.Size) assert.Equal(t, expected.Size, actual.Size)
assert.Equal(t, expected.DownloadCount, actual.DownloadCount) assert.Equal(t, expected.DownloadCount, actual.DownloadCount)
assertTimeEqual(t, expected.Created, actual.Created) assertTimeEqual(t, expected.Created, actual.Created)