Skip to content

Commit c58d97e

Browse files
committed
Merge branch 'main' into deps-api
2 parents 3c24b3b + d4f35bd commit c58d97e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+589
-349
lines changed

docs/content/doc/usage/pull-request.en-us.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,45 @@ menu:
1515

1616
# Pull Request
1717

18+
A Pull Request (PR) is a way to propose changes to a repository.
19+
It is a request to merge one branch into another, accompanied by a description of the changes that were made.
20+
Pull Requests are commonly used as a way for contributors to propose changes and for maintainers to review and merge those changes.
21+
22+
## Creating a pull request
23+
24+
To create a PR, you'll need to follow these steps:
25+
26+
1. **Fork the repository** - If you don't have permission to make changes to the repository directly, you'll need to fork the repository to your own account.
27+
This creates a copy of the repository that you can make changes to.
28+
29+
2. **Create a branch (optional)** - Create a new branch on your forked repository that contains the changes you want to propose.
30+
Give the branch a descriptive name that indicates what the changes are for.
31+
32+
3. **Make your changes** - Make the changes you want, commit, and push them to your forked repository.
33+
34+
4. **Create the PR** - Go to the original repository and go to the "Pull Requests" tab. Click the "New Pull Request" button and select your new branch as the source branch.
35+
Enter a descriptive title and description for your Pull Request and click "Create Pull Request".
36+
37+
## Reviewing a pull request
38+
39+
When a PR is created, it triggers a review process. The maintainers of the repository are notified of the PR and can review the changes that were made.
40+
They can leave comments, request changes, or approve the changes.
41+
42+
If the maintainers request changes, you'll need to make those changes in your branch and push the changes to your forked repository.
43+
The PR will be updated automatically with the new changes.
44+
45+
If the maintainers approve the changes, they can merge the PR into the repository.
46+
47+
## Closing a pull request
48+
49+
If you decide that you no longer want to merge a PR, you can close it.
50+
To close a PR, go to the open PR and click the "Close Pull Request" button. This will close the PR without merging it.
51+
1852
## "Work In Progress" pull requests
1953

20-
Marking a pull request as being a work in progress will prevent that pull request from being accidentally merged. To mark a pull request as being a work in progress, you must prefix its title by `WIP:` or `[WIP]` (case insensitive). Those values are configurable in your `app.ini` file :
54+
Marking a pull request as being a work in progress will prevent that pull request from being accidentally merged.
55+
To mark a pull request as being a work in progress, you must prefix its title by `WIP:` or `[WIP]` (case insensitive).
56+
Those values are configurable in your `app.ini` file:
2157

2258
```ini
2359
[repository.pull-request]

models/git/lfs_lock.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func init() {
3434

3535
// BeforeInsert is invoked from XORM before inserting an object of this type.
3636
func (l *LFSLock) BeforeInsert() {
37-
l.Path = util.CleanPath(l.Path)
37+
l.Path = util.PathJoinRel(l.Path)
3838
}
3939

4040
// CreateLFSLock creates a new lock.
@@ -49,7 +49,7 @@ func CreateLFSLock(ctx context.Context, repo *repo_model.Repository, lock *LFSLo
4949
return nil, err
5050
}
5151

52-
lock.Path = util.CleanPath(lock.Path)
52+
lock.Path = util.PathJoinRel(lock.Path)
5353
lock.RepoID = repo.ID
5454

5555
l, err := GetLFSLock(dbCtx, repo, lock.Path)
@@ -69,7 +69,7 @@ func CreateLFSLock(ctx context.Context, repo *repo_model.Repository, lock *LFSLo
6969

7070
// GetLFSLock returns release by given path.
7171
func GetLFSLock(ctx context.Context, repo *repo_model.Repository, path string) (*LFSLock, error) {
72-
path = util.CleanPath(path)
72+
path = util.PathJoinRel(path)
7373
rel := &LFSLock{RepoID: repo.ID}
7474
has, err := db.GetEngine(ctx).Where("lower(path) = ?", strings.ToLower(path)).Get(rel)
7575
if err != nil {

modules/options/base.go

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,38 @@ import (
77
"fmt"
88
"io/fs"
99
"os"
10-
"path"
1110
"path/filepath"
1211

12+
"code.gitea.io/gitea/modules/log"
1313
"code.gitea.io/gitea/modules/setting"
1414
"code.gitea.io/gitea/modules/util"
1515
)
1616

17+
var directories = make(directorySet)
18+
1719
// Locale reads the content of a specific locale from static/bindata or custom path.
1820
func Locale(name string) ([]byte, error) {
19-
return fileFromDir(path.Join("locale", util.CleanPath(name)))
21+
return fileFromOptionsDir("locale", name)
2022
}
2123

2224
// Readme reads the content of a specific readme from static/bindata or custom path.
2325
func Readme(name string) ([]byte, error) {
24-
return fileFromDir(path.Join("readme", util.CleanPath(name)))
26+
return fileFromOptionsDir("readme", name)
2527
}
2628

2729
// Gitignore reads the content of a gitignore locale from static/bindata or custom path.
2830
func Gitignore(name string) ([]byte, error) {
29-
return fileFromDir(path.Join("gitignore", util.CleanPath(name)))
31+
return fileFromOptionsDir("gitignore", name)
3032
}
3133

3234
// License reads the content of a specific license from static/bindata or custom path.
3335
func License(name string) ([]byte, error) {
34-
return fileFromDir(path.Join("license", util.CleanPath(name)))
36+
return fileFromOptionsDir("license", name)
3537
}
3638

3739
// Labels reads the content of a specific labels from static/bindata or custom path.
3840
func Labels(name string) ([]byte, error) {
39-
return fileFromDir(path.Join("label", util.CleanPath(name)))
41+
return fileFromOptionsDir("label", name)
4042
}
4143

4244
// WalkLocales reads the content of a specific locale
@@ -79,17 +81,54 @@ func walkAssetDir(root string, callback func(path, name string, d fs.DirEntry, e
7981
return nil
8082
}
8183

82-
func statDirIfExist(dir string) ([]string, error) {
83-
isDir, err := util.IsDir(dir)
84+
// mustLocalPathAbs coverts a path to absolute path
85+
// FIXME: the old behavior (StaticRootPath might not be absolute), not ideal, just keep the same as before
86+
func mustLocalPathAbs(s string) string {
87+
abs, err := filepath.Abs(s)
8488
if err != nil {
85-
return nil, fmt.Errorf("unable to check if static directory %s is a directory. %w", dir, err)
89+
// This should never happen in a real system. If it happens, the user must have already been in trouble: the system is not able to resolve its own paths.
90+
log.Fatal("Unable to get absolute path for %q: %v", s, err)
8691
}
87-
if !isDir {
88-
return nil, nil
92+
return abs
93+
}
94+
95+
func joinLocalPaths(baseDirs []string, subDir string, elems ...string) (paths []string) {
96+
abs := make([]string, len(elems)+2)
97+
abs[1] = subDir
98+
copy(abs[2:], elems)
99+
for _, baseDir := range baseDirs {
100+
abs[0] = mustLocalPathAbs(baseDir)
101+
paths = append(paths, util.FilePathJoinAbs(abs...))
89102
}
90-
files, err := util.StatDir(dir, true)
91-
if err != nil {
92-
return nil, fmt.Errorf("unable to read directory %q. %w", dir, err)
103+
return paths
104+
}
105+
106+
func listLocalDirIfExist(baseDirs []string, subDir string, elems ...string) (files []string, err error) {
107+
for _, localPath := range joinLocalPaths(baseDirs, subDir, elems...) {
108+
isDir, err := util.IsDir(localPath)
109+
if err != nil {
110+
return nil, fmt.Errorf("unable to check if path %q is a directory. %w", localPath, err)
111+
} else if !isDir {
112+
continue
113+
}
114+
115+
dirFiles, err := util.StatDir(localPath, true)
116+
if err != nil {
117+
return nil, fmt.Errorf("unable to read directory %q. %w", localPath, err)
118+
}
119+
files = append(files, dirFiles...)
93120
}
94121
return files, nil
95122
}
123+
124+
func readLocalFile(baseDirs []string, subDir string, elems ...string) ([]byte, error) {
125+
for _, localPath := range joinLocalPaths(baseDirs, subDir, elems...) {
126+
data, err := os.ReadFile(localPath)
127+
if err == nil {
128+
return data, nil
129+
} else if !os.IsNotExist(err) {
130+
log.Error("Unable to read file %q. Error: %v", localPath, err)
131+
}
132+
}
133+
return nil, os.ErrNotExist
134+
}

modules/options/dynamic.go

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,62 +6,26 @@
66
package options
77

88
import (
9-
"fmt"
10-
"os"
11-
"path"
12-
13-
"code.gitea.io/gitea/modules/log"
149
"code.gitea.io/gitea/modules/setting"
15-
"code.gitea.io/gitea/modules/util"
1610
)
1711

18-
var directories = make(directorySet)
19-
2012
// Dir returns all files from static or custom directory.
2113
func Dir(name string) ([]string, error) {
2214
if directories.Filled(name) {
2315
return directories.Get(name), nil
2416
}
2517

26-
var result []string
27-
28-
for _, dir := range []string{
29-
path.Join(setting.CustomPath, "options", name), // custom dir
30-
path.Join(setting.StaticRootPath, "options", name), // static dir
31-
} {
32-
files, err := statDirIfExist(dir)
33-
if err != nil {
34-
return nil, err
35-
}
36-
result = append(result, files...)
18+
result, err := listLocalDirIfExist([]string{setting.CustomPath, setting.StaticRootPath}, "options", name)
19+
if err != nil {
20+
return nil, err
3721
}
3822

3923
return directories.AddAndGet(name, result), nil
4024
}
4125

42-
// fileFromDir is a helper to read files from static or custom path.
43-
func fileFromDir(name string) ([]byte, error) {
44-
customPath := path.Join(setting.CustomPath, "options", name)
45-
46-
isFile, err := util.IsFile(customPath)
47-
if err != nil {
48-
log.Error("Unable to check if %s is a file. Error: %v", customPath, err)
49-
}
50-
if isFile {
51-
return os.ReadFile(customPath)
52-
}
53-
54-
staticPath := path.Join(setting.StaticRootPath, "options", name)
55-
56-
isFile, err = util.IsFile(staticPath)
57-
if err != nil {
58-
log.Error("Unable to check if %s is a file. Error: %v", staticPath, err)
59-
}
60-
if isFile {
61-
return os.ReadFile(staticPath)
62-
}
63-
64-
return []byte{}, fmt.Errorf("Asset file does not exist: %s", name)
26+
// fileFromOptionsDir is a helper to read files from custom or static path.
27+
func fileFromOptionsDir(elems ...string) ([]byte, error) {
28+
return readLocalFile([]string{setting.CustomPath, setting.StaticRootPath}, "options", elems...)
6529
}
6630

6731
// IsDynamic will return false when using embedded data (-tags bindata)

modules/options/static.go

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,20 @@ package options
88
import (
99
"fmt"
1010
"io"
11-
"os"
12-
"path"
1311

14-
"code.gitea.io/gitea/modules/log"
1512
"code.gitea.io/gitea/modules/setting"
1613
"code.gitea.io/gitea/modules/util"
1714
)
1815

19-
var directories = make(directorySet)
20-
21-
// Dir returns all files from bindata or custom directory.
16+
// Dir returns all files from custom directory or bindata.
2217
func Dir(name string) ([]string, error) {
2318
if directories.Filled(name) {
2419
return directories.Get(name), nil
2520
}
2621

27-
var result []string
28-
29-
for _, dir := range []string{
30-
path.Join(setting.CustomPath, "options", name), // custom dir
31-
// no static dir
32-
} {
33-
files, err := statDirIfExist(dir)
34-
if err != nil {
35-
return nil, err
36-
}
37-
result = append(result, files...)
22+
result, err := listLocalDirIfExist([]string{setting.CustomPath}, "options", name)
23+
if err != nil {
24+
return nil, err
3825
}
3926

4027
files, err := AssetDir(name)
@@ -64,24 +51,18 @@ func AssetDir(dirName string) ([]string, error) {
6451
return results, nil
6552
}
6653

67-
// fileFromDir is a helper to read files from bindata or custom path.
68-
func fileFromDir(name string) ([]byte, error) {
69-
customPath := path.Join(setting.CustomPath, "options", name)
70-
71-
isFile, err := util.IsFile(customPath)
72-
if err != nil {
73-
log.Error("Unable to check if %s is a file. Error: %v", customPath, err)
74-
}
75-
if isFile {
76-
return os.ReadFile(customPath)
54+
// fileFromOptionsDir is a helper to read files from custom path or bindata.
55+
func fileFromOptionsDir(elems ...string) ([]byte, error) {
56+
// only try custom dir, no static dir
57+
if data, err := readLocalFile([]string{setting.CustomPath}, "options", elems...); err == nil {
58+
return data, nil
7759
}
7860

79-
f, err := Assets.Open(name)
61+
f, err := Assets.Open(util.PathJoinRelX(elems...))
8062
if err != nil {
8163
return nil, err
8264
}
8365
defer f.Close()
84-
8566
return io.ReadAll(f)
8667
}
8768

modules/public/public.go

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,19 @@ func AssetsHandlerFunc(opts *Options) http.HandlerFunc {
4545
return
4646
}
4747

48-
file := req.URL.Path
49-
file = file[len(opts.Prefix):]
50-
if len(file) == 0 {
51-
resp.WriteHeader(http.StatusNotFound)
52-
return
53-
}
54-
if strings.Contains(file, "\\") {
55-
resp.WriteHeader(http.StatusBadRequest)
56-
return
57-
}
58-
file = "/" + file
59-
60-
var written bool
48+
var corsSent bool
6149
if opts.CorsHandler != nil {
62-
written = true
6350
opts.CorsHandler(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
64-
written = false
51+
corsSent = true
6552
})).ServeHTTP(resp, req)
6653
}
67-
if written {
54+
// If CORS is not sent, the response must have been written by other handlers
55+
if !corsSent {
6856
return
6957
}
7058

59+
file := req.URL.Path[len(opts.Prefix):]
60+
7161
// custom files
7262
if opts.handle(resp, req, http.Dir(custPath), file) {
7363
return
@@ -102,8 +92,8 @@ func setWellKnownContentType(w http.ResponseWriter, file string) {
10292
}
10393

10494
func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
105-
// use clean to keep the file is a valid path with no . or ..
106-
f, err := fs.Open(util.CleanPath(file))
95+
// actually, fs (http.FileSystem) is designed to be a safe interface, relative paths won't bypass its parent directory, it's also fine to do a clean here
96+
f, err := fs.Open(util.PathJoinRelX(file))
10797
if err != nil {
10898
if os.IsNotExist(err) {
10999
return false

0 commit comments

Comments
 (0)