Skip to content

Commit 166c6bb

Browse files
authored
Merge branch 'main' into optimize-filetree-icons-match
2 parents 473a3f1 + bcc38eb commit 166c6bb

File tree

11 files changed

+87
-31
lines changed

11 files changed

+87
-31
lines changed

modules/markup/html.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ var globalVars = sync.OnceValue(func() *globalVarsType {
8585
// codePreviewPattern matches "http://domain/.../{owner}/{repo}/src/commit/{commit}/{filepath}#L10-L20"
8686
v.codePreviewPattern = regexp.MustCompile(`https?://\S+/([^\s/]+)/([^\s/]+)/src/commit/([0-9a-f]{7,64})(/\S+)#(L\d+(-L\d+)?)`)
8787

88-
v.tagCleaner = regexp.MustCompile(`<((?:/?\w+/\w+)|(?:/[\w ]+/)|(/?[hH][tT][mM][lL]\b)|(/?[hH][eE][aA][dD]\b))`)
88+
// cleans: "<foo/bar", "<any words/", ("<html", "<head", "<script", "<style")
89+
v.tagCleaner = regexp.MustCompile(`(?i)<(/?\w+/\w+|/[\w ]+/|/?(html|head|script|style\b))`)
8990
v.nulCleaner = strings.NewReplacer("\000", "")
9091
return v
9192
})

modules/markup/html_test.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ func Test_ParseClusterFuzz(t *testing.T) {
469469
assert.NotContains(t, res.String(), "<html")
470470
}
471471

472-
func TestPostProcess_RenderDocument(t *testing.T) {
472+
func TestPostProcess(t *testing.T) {
473473
setting.StaticURLPrefix = markup.TestAppURL // can't run standalone
474474
defer testModule.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, true)()
475475

@@ -480,7 +480,7 @@ func TestPostProcess_RenderDocument(t *testing.T) {
480480
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res.String()))
481481
}
482482

483-
// Issue index shouldn't be post processing in a document.
483+
// Issue index shouldn't be post-processing in a document.
484484
test(
485485
"#1",
486486
"#1")
@@ -490,7 +490,7 @@ func TestPostProcess_RenderDocument(t *testing.T) {
490490
"go-gitea/gitea#12345",
491491
`<a href="/go-gitea/gitea/issues/12345" class="ref-issue">go-gitea/gitea#12345</a>`)
492492

493-
// Test that other post processing still works.
493+
// Test that other post-processing still works.
494494
test(
495495
":gitea:",
496496
`<span class="emoji" aria-label="gitea"><img alt=":gitea:" src="`+setting.StaticURLPrefix+`/assets/img/emoji/gitea.png"/></span>`)
@@ -499,6 +499,12 @@ func TestPostProcess_RenderDocument(t *testing.T) {
499499
`Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span> in the middle`)
500500
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
501501
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4 (comment)</a>`)
502+
503+
// special tags, GitHub's behavior, and for unclosed tags, output as text content as much as possible
504+
test("<script>a", `&lt;script&gt;a`)
505+
test("<script>a</script>", `&lt;script&gt;a&lt;/script&gt;`)
506+
test("<STYLE>a", `&lt;STYLE&gt;a`)
507+
test("<style>a</STYLE>", `&lt;style&gt;a&lt;/STYLE&gt;`)
502508
}
503509

504510
func TestIssue16020(t *testing.T) {

routers/web/repo/view_home.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
unit_model "code.gitea.io/gitea/models/unit"
2121
user_model "code.gitea.io/gitea/models/user"
2222
"code.gitea.io/gitea/modules/git"
23+
giturl "code.gitea.io/gitea/modules/git/url"
24+
"code.gitea.io/gitea/modules/httplib"
2325
"code.gitea.io/gitea/modules/log"
2426
repo_module "code.gitea.io/gitea/modules/repository"
2527
"code.gitea.io/gitea/modules/setting"
@@ -302,8 +304,33 @@ func handleRepoEmptyOrBroken(ctx *context.Context) {
302304
ctx.Redirect(link)
303305
}
304306

307+
func handleRepoViewSubmodule(ctx *context.Context, submodule *git.SubModule) {
308+
submoduleRepoURL, err := giturl.ParseRepositoryURL(ctx, submodule.URL)
309+
if err != nil {
310+
HandleGitError(ctx, "prepareToRenderDirOrFile: ParseRepositoryURL", err)
311+
return
312+
}
313+
submoduleURL := giturl.MakeRepositoryWebLink(submoduleRepoURL)
314+
if httplib.IsCurrentGiteaSiteURL(ctx, submoduleURL) {
315+
ctx.RedirectToCurrentSite(submoduleURL)
316+
} else {
317+
// don't auto-redirect to external URL, to avoid open redirect or phishing
318+
ctx.Data["NotFoundPrompt"] = submoduleURL
319+
ctx.NotFound(nil)
320+
}
321+
}
322+
305323
func prepareToRenderDirOrFile(entry *git.TreeEntry) func(ctx *context.Context) {
306324
return func(ctx *context.Context) {
325+
if entry.IsSubModule() {
326+
submodule, err := ctx.Repo.Commit.GetSubModule(entry.Name())
327+
if err != nil {
328+
HandleGitError(ctx, "prepareToRenderDirOrFile: GetSubModule", err)
329+
return
330+
}
331+
handleRepoViewSubmodule(ctx, submodule)
332+
return
333+
}
307334
if entry.IsDir() {
308335
prepareToRenderDirectory(ctx)
309336
} else {

routers/web/repo/view_home_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package repo
5+
6+
import (
7+
"net/http"
8+
"testing"
9+
10+
"code.gitea.io/gitea/models/unittest"
11+
git_module "code.gitea.io/gitea/modules/git"
12+
"code.gitea.io/gitea/modules/setting"
13+
"code.gitea.io/gitea/services/contexttest"
14+
15+
"github.com/stretchr/testify/assert"
16+
)
17+
18+
func TestViewHomeSubmoduleRedirect(t *testing.T) {
19+
unittest.PrepareTestEnv(t)
20+
21+
ctx, _ := contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule")
22+
submodule := &git_module.SubModule{Path: "test-submodule", URL: setting.AppURL + "user2/repo-other.git"}
23+
handleRepoViewSubmodule(ctx, submodule)
24+
assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus())
25+
assert.Equal(t, "/user2/repo-other", ctx.Resp.Header().Get("Location"))
26+
27+
ctx, _ = contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule")
28+
submodule = &git_module.SubModule{Path: "test-submodule", URL: "https://other/user2/repo-other.git"}
29+
handleRepoViewSubmodule(ctx, submodule)
30+
// do not auto-redirect for external URLs, to avoid open redirect or phishing
31+
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus())
32+
}

routers/web/web.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ func registerWebRoutes(m *web.Router) {
12111211
m.Get("/comments/{id}/attachments", repo.GetCommentAttachments)
12121212
m.Get("/labels", repo.RetrieveLabelsForList, repo.Labels)
12131213
m.Get("/milestones", repo.Milestones)
1214-
m.Get("/milestone/{id}", context.RepoRef(), repo.MilestoneIssuesAndPulls)
1214+
m.Get("/milestone/{id}", repo.MilestoneIssuesAndPulls)
12151215
m.Get("/issues/suggestions", repo.IssueSuggestions)
12161216
}, optSignIn, context.RepoAssignment, reqRepoIssuesOrPullsReader) // issue/pull attachments, labels, milestones
12171217
// end "/{username}/{reponame}": view milestone, label, issue, pull, etc
@@ -1225,9 +1225,9 @@ func registerWebRoutes(m *web.Router) {
12251225
m.Group("/{username}/{reponame}", func() { // edit issues, pulls, labels, milestones, etc
12261226
m.Group("/issues", func() {
12271227
m.Group("/new", func() {
1228-
m.Combo("").Get(context.RepoRef(), repo.NewIssue).
1228+
m.Combo("").Get(repo.NewIssue).
12291229
Post(web.Bind(forms.CreateIssueForm{}), repo.NewIssuePost)
1230-
m.Get("/choose", context.RepoRef(), repo.NewIssueChooseTemplate)
1230+
m.Get("/choose", repo.NewIssueChooseTemplate)
12311231
})
12321232
m.Get("/search", repo.SearchRepoIssuesJSON)
12331233
}, reqUnitIssuesReader)
@@ -1290,7 +1290,7 @@ func registerWebRoutes(m *web.Router) {
12901290
m.Post("/edit", web.Bind(forms.CreateLabelForm{}), repo.UpdateLabel)
12911291
m.Post("/delete", repo.DeleteLabel)
12921292
m.Post("/initialize", web.Bind(forms.InitializeLabelsForm{}), repo.InitializeLabels)
1293-
}, reqRepoIssuesOrPullsWriter, context.RepoRef())
1293+
}, reqRepoIssuesOrPullsWriter)
12941294

12951295
m.Group("/milestones", func() {
12961296
m.Combo("/new").Get(repo.NewMilestone).
@@ -1299,7 +1299,7 @@ func registerWebRoutes(m *web.Router) {
12991299
m.Post("/{id}/edit", web.Bind(forms.CreateMilestoneForm{}), repo.EditMilestonePost)
13001300
m.Post("/{id}/{action}", repo.ChangeMilestoneStatus)
13011301
m.Post("/delete", repo.DeleteMilestone)
1302-
}, reqRepoIssuesOrPullsWriter, context.RepoRef())
1302+
}, reqRepoIssuesOrPullsWriter)
13031303

13041304
// FIXME: many "pulls" requests are sent to "issues" endpoints incorrectly, need to move these routes to the proper place
13051305
m.Group("/issues", func() {
@@ -1377,7 +1377,7 @@ func registerWebRoutes(m *web.Router) {
13771377
m.Post("/delete", repo.DeleteRelease)
13781378
m.Post("/attachments", repo.UploadReleaseAttachment)
13791379
m.Post("/attachments/remove", repo.DeleteAttachment)
1380-
}, reqSignIn, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef())
1380+
}, reqSignIn, context.RepoMustNotBeArchived(), reqRepoReleaseWriter)
13811381
m.Group("/releases", func() {
13821382
m.Get("/edit/*", repo.EditRelease)
13831383
m.Post("/edit/*", web.Bind(forms.EditReleaseForm{}), repo.EditReleasePost)
@@ -1506,19 +1506,19 @@ func registerWebRoutes(m *web.Router) {
15061506
m.Get(".diff", repo.DownloadPullDiff)
15071507
m.Get(".patch", repo.DownloadPullPatch)
15081508
m.Group("/commits", func() {
1509-
m.Get("", context.RepoRef(), repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits)
1510-
m.Get("/list", context.RepoRef(), repo.GetPullCommits)
1511-
m.Get("/{sha:[a-f0-9]{7,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit)
1509+
m.Get("", repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits)
1510+
m.Get("/list", repo.GetPullCommits)
1511+
m.Get("/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit)
15121512
})
15131513
m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest)
15141514
m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest)
15151515
m.Post("/update", repo.UpdatePullRequest)
15161516
m.Post("/set_allow_maintainer_edit", web.Bind(forms.UpdateAllowEditsForm{}), repo.SetAllowEdits)
1517-
m.Post("/cleanup", context.RepoMustNotBeArchived(), context.RepoRef(), repo.CleanUpPullRequest)
1517+
m.Post("/cleanup", context.RepoMustNotBeArchived(), repo.CleanUpPullRequest)
15181518
m.Group("/files", func() {
1519-
m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForAllCommitsOfPr)
1520-
m.Get("/{sha:[a-f0-9]{7,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesStartingFromCommit)
1521-
m.Get("/{shaFrom:[a-f0-9]{7,40}}..{shaTo:[a-f0-9]{7,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForRange)
1519+
m.Get("", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForAllCommitsOfPr)
1520+
m.Get("/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesStartingFromCommit)
1521+
m.Get("/{shaFrom:[a-f0-9]{7,40}}..{shaTo:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForRange)
15221522
m.Group("/reviews", func() {
15231523
m.Get("/new_comment", repo.RenderNewCodeCommentForm)
15241524
m.Post("/comments", web.Bind(forms.CodeCommentForm{}), repo.SetShowOutdatedComments, repo.CreateCodeComment)
@@ -1605,7 +1605,7 @@ func registerWebRoutes(m *web.Router) {
16051605
m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*"
16061606
m.Get("/blob/*", repo.RedirectRepoBlobToCommit) // redirect "/owner/repo/blob/*" requests to "/owner/repo/src/commit/*"
16071607

1608-
m.Get("/forks", context.RepoRef(), repo.Forks)
1608+
m.Get("/forks", repo.Forks)
16091609
m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff)
16101610
m.Post("/lastcommit/*", context.RepoRefByType(git.RefTypeCommit), repo.LastCommit)
16111611
}, optSignIn, context.RepoAssignment, reqUnitCodeReader)

services/context/repo.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -669,12 +669,6 @@ func RepoAssignment(ctx *Context) {
669669

670670
const headRefName = "HEAD"
671671

672-
func RepoRef() func(*Context) {
673-
// old code does: return RepoRefByType(git.RefTypeBranch)
674-
// in most cases, it is an abuse, so we just disable it completely and fix the abuses one by one (if there is anything wrong)
675-
return nil
676-
}
677-
678672
func getRefNameFromPath(repo *Repository, path string, isExist func(string) bool) string {
679673
refName := ""
680674
parts := strings.Split(path, "/")

templates/status/500.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
{{if .ErrorMsg}}
3939
<div class="tw-mt-8">
4040
<p>{{ctx.Locale.Tr "error.occurred"}}:</p>
41-
<pre class="tw-whitespace-pre-wrap tw-break-all">{{.ErrorMsg}}</pre>
41+
<pre class="tw-whitespace-pre-wrap tw-wrap-anywhere">{{.ErrorMsg}}</pre>
4242
</div>
4343
{{end}}
4444
<div class="tw-mt-8 tw-text-center">

web_src/css/base.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,6 @@ overflow-menu .ui.label {
878878
.code-inner {
879879
font: 12px var(--fonts-monospace);
880880
white-space: pre-wrap;
881-
word-break: break-all;
882881
overflow-wrap: anywhere;
883882
line-height: inherit; /* needed for inline code preview in markup */
884883
}

web_src/css/markup/content.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,7 @@
447447
margin: 0;
448448
font-size: 100%;
449449
white-space: pre-wrap;
450-
word-break: break-all;
451-
overflow-wrap: break-word;
450+
overflow-wrap: anywhere;
452451
background: transparent;
453452
border: 0;
454453
}

web_src/css/repo.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,8 +1724,7 @@ tbody.commit-list {
17241724
line-height: 18px;
17251725
margin: 1em;
17261726
white-space: pre-wrap;
1727-
word-break: break-all;
1728-
overflow-wrap: break-word;
1727+
overflow-wrap: anywhere;
17291728
}
17301729

17311730
.content-history-detail-dialog .header .avatar {

0 commit comments

Comments
 (0)