Commit 18da8c33b3

18da8c33b3c0caf1f457ef638eeccd9c2e8a47de

parent: 504b4d488c

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-09-29 03:32 UTC

backup: verify skips LFS upload staging files; asset label names a missing repository by id

Ref #259

Layout: unified · split

cmd/gitbayd/backup.go +10 −4
@@ -24,6 +24,7 @@ import (
2424 "gitbay.org/gitbay/internal/backuplock"
2525 "gitbay.org/gitbay/internal/config"
2626 "gitbay.org/gitbay/internal/gitutil"
27 "gitbay.org/gitbay/internal/lfs"
2728 "gitbay.org/gitbay/internal/store"
2829)
2930
@@ -514,9 +515,10 @@ func checkArchive(path, identity, dest string, full bool) error {
514515 if err := extractTo(tr, dbPath); err != nil {
515516 return fmt.Errorf("%s: extracting the database: %w", path, err)
516517 }
517 case strings.HasPrefix(h.Name, "lfs/") && h.Typeflag == tar.TypeReg:
518 case strings.HasPrefix(h.Name, "lfs/") && h.Typeflag == tar.TypeReg && lfs.OIDPat.MatchString(filepath.Base(h.Name)):
518519 // Objects are named by their sha256, so each is checked as it
519 // streams past and none is extracted.
520 // streams past and none is extracted. Other names, such as an
521 // upload's .upload-* staging file, are not objects.
520522 lfsObjects++
521523 if !filepath.IsLocal(h.Name) {
522524 return fmt.Errorf("%s: member %q leaves the archive root", path, h.Name)
@@ -664,8 +666,12 @@ func checkReleaseAssets(st *store.Store, repos []store.Repo, root string) (int,
664666 return 0, nil, err
665667 }
666668 n++
667 r := byID[repoID]
668 label := fmt.Sprintf("%s release %d %s", r.Path(), relID, name)
669 r, ok := byID[repoID]
670 owner := r.Path()
671 if !ok {
672 owner = fmt.Sprintf("repository %d", repoID)
673 }
674 label := fmt.Sprintf("%s release %d %s", owner, relID, name)
669675 f, err := os.Open(filepath.Join(root, "repos", r.OwnerName, r.Name+".git", "gitbay-releases", strconv.FormatInt(relID, 10), name))
670676 if err != nil {
671677 bad = append(bad, label)
cmd/gitbayd/backup_test.go +4 −2
@@ -879,6 +879,8 @@ func TestVerifyChecksReleaseAssetsAndLFS(t *testing.T) {
879879 oid := sha256.Sum256(obj)
880880 o := hex.EncodeToString(oid[:])
881881 writeFile(t, filepath.Join(root, "lfs", o[:2], o[2:4], o), obj)
882 // An upload in progress stages a temporary file beside the objects.
883 writeFile(t, filepath.Join(root, "lfs", o[:2], o[2:4], ".upload-123"), []byte("partial"))
882884
883885 good := filepath.Join(t.TempDir(), "good.tar.gz")
884886 if err := runBackup(cfg, good, false); err != nil {
@@ -899,8 +901,8 @@ func TestVerifyChecksReleaseAssetsAndLFS(t *testing.T) {
899901 if err == nil || !strings.Contains(err.Error(), "krz/thing release") || !strings.Contains(err.Error(), wrong) {
900902 t.Fatalf("archive with a bad asset and LFS object: %v", err)
901903 }
902 if strings.Contains(err.Error(), o) {
903 t.Fatalf("intact LFS object reported: %v", err)
904 if strings.Contains(err.Error(), o) || strings.Contains(err.Error(), ".upload-") {
905 t.Fatalf("intact LFS object or upload staging file reported: %v", err)
904906 }
905907}
906908