diff options
author | zeripath <art27@cantab.net> | 2021-12-16 19:01:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-16 19:01:14 +0000 |
commit | 83546707085af9b59bdefdfbb2dc5511dadb57d7 (patch) | |
tree | a4ab94f79e8d8fc471e1e324a1e155d4c3e7fb4f /models | |
parent | 6e7d28cf3aef9e91c435f841ec217bff5c750b87 (diff) | |
download | gitea-83546707085af9b59bdefdfbb2dc5511dadb57d7.tar.gz gitea-83546707085af9b59bdefdfbb2dc5511dadb57d7.zip |
Prevent hang in git cat-file if repository is not a valid repository and other fixes (#17991)
This PR contains multiple fixes. The most important of which is:
* Prevent hang in git cat-file if the repository is not a valid repository
Unfortunately it appears that if git cat-file is run in an invalid
repository it will hang until stdin is closed. This will result in
deadlocked /pulls pages and dangling git cat-file calls if a broken
repository is tried to be reviewed or pulls exists for a broken
repository.
Fix #14734
Fix #9271
Fix #16113
Otherwise there are a few small other fixes included which this PR was initially intending to fix:
* Fix panic on partial compares due to missing PullRequestWorkInProgressPrefixes
* Fix links on pulls pages due to regression from #17551 - by making most /issues routes match /pulls too - Fix #17983
* Fix links on feeds pages due to another regression from #17551 but also fix issue with syncing tags - Fix #17943
* Add missing locale entries for oauth group claims
* Prevent NPEs if ColorFormat is called on nil users, repos or teams.
Diffstat (limited to 'models')
-rw-r--r-- | models/action.go | 16 | ||||
-rw-r--r-- | models/migrations/migrations_test.go | 19 | ||||
-rw-r--r-- | models/org_team.go | 8 | ||||
-rw-r--r-- | models/repo/repo.go | 7 | ||||
-rw-r--r-- | models/unittest/testdb.go | 37 | ||||
-rw-r--r-- | models/user/user.go | 6 |
6 files changed, 93 insertions, 0 deletions
diff --git a/models/action.go b/models/action.go index da9e6776b1..26d05730c5 100644 --- a/models/action.go +++ b/models/action.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -252,6 +253,21 @@ func (a *Action) GetBranch() string { return strings.TrimPrefix(a.RefName, git.BranchPrefix) } +// GetRefLink returns the action's ref link. +func (a *Action) GetRefLink() string { + switch { + case strings.HasPrefix(a.RefName, git.BranchPrefix): + return a.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.BranchPrefix)) + case strings.HasPrefix(a.RefName, git.TagPrefix): + return a.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.TagPrefix)) + case len(a.RefName) == 40 && git.SHAPattern.MatchString(a.RefName): + return a.GetRepoLink() + "/src/commit/" + a.RefName + default: + // FIXME: we will just assume it's a branch - this was the old way - at some point we may want to enforce that there is always a ref here. + return a.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.BranchPrefix)) + } +} + // GetTag returns the action's repository tag. func (a *Action) GetTag() string { return strings.TrimPrefix(a.RefName, git.TagPrefix) diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go index 10ba3dde09..ceef0954e1 100644 --- a/models/migrations/migrations_test.go +++ b/models/migrations/migrations_test.go @@ -207,6 +207,25 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En assert.NoError(t, com.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) + ownerDirs, err := os.ReadDir(setting.RepoRootPath) + if err != nil { + assert.NoError(t, err, "unable to read the new repo root: %v\n", err) + } + for _, ownerDir := range ownerDirs { + if !ownerDir.Type().IsDir() { + continue + } + repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name())) + if err != nil { + assert.NoError(t, err, "unable to read the new repo root: %v\n", err) + } + for _, repoDir := range repoDirs { + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0755) + } + } if err := deleteDB(); err != nil { t.Errorf("unable to reset database: %v", err) diff --git a/models/org_team.go b/models/org_team.go index 3d4a2882c7..7eac0f7bc5 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -114,6 +114,14 @@ func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { // ColorFormat provides a basic color format for a Team func (t *Team) ColorFormat(s fmt.State) { + if t == nil { + log.ColorFprintf(s, "%d:%s (OrgID: %d) %-v", + log.NewColoredIDValue(0), + "<nil>", + log.NewColoredIDValue(0), + 0) + return + } log.ColorFprintf(s, "%d:%s (OrgID: %d) %-v", log.NewColoredIDValue(t.ID), t.Name, diff --git a/models/repo/repo.go b/models/repo/repo.go index 43ac9fb62a..d0136e9c66 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -173,6 +173,13 @@ func (repo *Repository) SanitizedOriginalURL() string { // ColorFormat returns a colored string to represent this repo func (repo *Repository) ColorFormat(s fmt.State) { + if repo == nil { + log.ColorFprintf(s, "%d:%s/%s", + log.NewColoredIDValue(0), + "<nil>", + "<nil>") + return + } log.ColorFprintf(s, "%d:%s/%s", log.NewColoredIDValue(repo.ID), repo.OwnerName, diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go index 8083c607e5..c798dbefb1 100644 --- a/models/unittest/testdb.go +++ b/models/unittest/testdb.go @@ -104,6 +104,26 @@ func MainTest(m *testing.M, pathToGiteaRoot string, fixtureFiles ...string) { fatalTestError("util.CopyDir: %v\n", err) } + ownerDirs, err := os.ReadDir(setting.RepoRootPath) + if err != nil { + fatalTestError("unable to read the new repo root: %v\n", err) + } + for _, ownerDir := range ownerDirs { + if !ownerDir.Type().IsDir() { + continue + } + repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name())) + if err != nil { + fatalTestError("unable to read the new repo root: %v\n", err) + } + for _, repoDir := range repoDirs { + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0755) + } + } + exitStatus := m.Run() if err = util.RemoveAll(repoRootPath); err != nil { fatalTestError("util.RemoveAll: %v\n", err) @@ -152,5 +172,22 @@ func PrepareTestEnv(t testing.TB) { assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta") assert.NoError(t, util.CopyDir(metaPath, setting.RepoRootPath)) + + ownerDirs, err := os.ReadDir(setting.RepoRootPath) + assert.NoError(t, err) + for _, ownerDir := range ownerDirs { + if !ownerDir.Type().IsDir() { + continue + } + repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name())) + assert.NoError(t, err) + for _, repoDir := range repoDirs { + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0755) + } + } + base.SetupGiteaRoot() // Makes sure GITEA_ROOT is set } diff --git a/models/user/user.go b/models/user/user.go index 80ddcdba37..d56a225d5f 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -160,6 +160,12 @@ type SearchOrganizationsOptions struct { // ColorFormat writes a colored string to identify this struct func (u *User) ColorFormat(s fmt.State) { + if u == nil { + log.ColorFprintf(s, "%d:%s", + log.NewColoredIDValue(0), + log.NewColoredValue("<nil>")) + return + } log.ColorFprintf(s, "%d:%s", log.NewColoredIDValue(u.ID), log.NewColoredValue(u.Name)) |