mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-10 15:32:55 +09:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0b8e3c8e1 | ||
|
|
7ff8e863a5 | ||
|
|
c65e49d72f | ||
|
|
50084daa4c | ||
|
|
c7db7438b7 | ||
|
|
e11f042a95 | ||
|
|
87782636e6 | ||
|
|
b935472cdf | ||
|
|
8ac48584ec | ||
|
|
e898590c81 | ||
|
|
d407857d97 |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -4,6 +4,19 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.14.4](https://github.com/go-gitea/gitea/releases/tag/v1.14.4) - 2021-07-06
|
||||
|
||||
* BUGFIXES
|
||||
* Fix relative links in postprocessed images (#16334) (#16340)
|
||||
* Fix list_options GetStartEnd (#16303) (#16305)
|
||||
* Fix API to use author for commits instead of committer (#16276) (#16277)
|
||||
* Handle misencoding of login_source cfg in mssql (#16268) (#16275)
|
||||
* Fixed issues not updated by commits (#16254) (#16261)
|
||||
* Improve efficiency in FindRenderizableReferenceNumeric and getReference (#16251) (#16255)
|
||||
* Use html.Parse rather than html.ParseFragment (#16223) (#16225)
|
||||
* Fix milestone counters on new issue (#16183) (#16224)
|
||||
* reqOrgMembership calls need to be preceded by reqToken (#16198) (#16219)
|
||||
|
||||
## [1.14.3](https://github.com/go-gitea/gitea/releases/tag/v1.14.3) - 2021-06-10
|
||||
|
||||
* SECURITY
|
||||
|
||||
@@ -144,7 +144,9 @@ func TestAPITeamSearch(t *testing.T) {
|
||||
var results TeamSearchResults
|
||||
|
||||
session := loginUser(t, user.Name)
|
||||
csrf := GetCSRF(t, session, "/"+org.Name)
|
||||
req := NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s", org.Name, "_team")
|
||||
req.Header.Add("X-Csrf-Token", csrf)
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &results)
|
||||
assert.NotEmpty(t, results.Data)
|
||||
@@ -154,7 +156,9 @@ func TestAPITeamSearch(t *testing.T) {
|
||||
// no access if not organization member
|
||||
user5 := models.AssertExistsAndLoadBean(t, &models.User{ID: 5}).(*models.User)
|
||||
session = loginUser(t, user5.Name)
|
||||
csrf = GetCSRF(t, session, "/"+org.Name)
|
||||
req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s", org.Name, "team")
|
||||
req.Header.Add("X-Csrf-Token", csrf)
|
||||
resp = session.MakeRequest(t, req, http.StatusForbidden)
|
||||
|
||||
}
|
||||
|
||||
@@ -141,6 +141,12 @@ func (milestone *Milestone) checkForConsistency(t *testing.T) {
|
||||
actual := getCount(t, x.Where("is_closed=?", true), &Issue{MilestoneID: milestone.ID})
|
||||
assert.EqualValues(t, milestone.NumClosedIssues, actual,
|
||||
"Unexpected number of closed issues for milestone %+v", milestone)
|
||||
|
||||
completeness := 0
|
||||
if milestone.NumIssues > 0 {
|
||||
completeness = milestone.NumClosedIssues * 100 / milestone.NumIssues
|
||||
}
|
||||
assert.Equal(t, completeness, milestone.Completeness)
|
||||
}
|
||||
|
||||
func (label *Label) checkForConsistency(t *testing.T) {
|
||||
|
||||
@@ -648,9 +648,11 @@ func (issue *Issue) doChangeStatus(e *xorm.Session, doer *User, isMergePull bool
|
||||
}
|
||||
|
||||
// Update issue count of milestone
|
||||
if err := updateMilestoneClosedNum(e, issue.MilestoneID); err != nil {
|
||||
if issue.MilestoneID > 0 {
|
||||
if err := updateMilestoneCounters(e, issue.MilestoneID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := issue.updateClosedNum(e); err != nil {
|
||||
return nil, err
|
||||
@@ -912,7 +914,7 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
||||
opts.Issue.Index = inserted.Index
|
||||
|
||||
if opts.Issue.MilestoneID > 0 {
|
||||
if _, err = e.Exec("UPDATE `milestone` SET num_issues=num_issues+1 WHERE id=?", opts.Issue.MilestoneID); err != nil {
|
||||
if err := updateMilestoneCounters(e, opts.Issue.MilestoneID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -129,8 +129,12 @@ func GetMilestoneByRepoIDANDName(repoID int64, name string) (*Milestone, error)
|
||||
|
||||
// GetMilestoneByID returns the milestone via id .
|
||||
func GetMilestoneByID(id int64) (*Milestone, error) {
|
||||
return getMilestoneByID(x, id)
|
||||
}
|
||||
|
||||
func getMilestoneByID(e Engine, id int64) (*Milestone, error) {
|
||||
var m Milestone
|
||||
has, err := x.ID(id).Get(&m)
|
||||
has, err := e.ID(id).Get(&m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
@@ -155,10 +159,6 @@ func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updateMilestoneCompleteness(sess, m.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if IsClosed changed, update milestone numbers of repository
|
||||
if oldIsClosed != m.IsClosed {
|
||||
if err := updateRepoMilestoneNum(sess, m.RepoID); err != nil {
|
||||
@@ -171,23 +171,31 @@ func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
|
||||
|
||||
func updateMilestone(e Engine, m *Milestone) error {
|
||||
m.Name = strings.TrimSpace(m.Name)
|
||||
_, err := e.ID(m.ID).AllCols().
|
||||
_, err := e.ID(m.ID).AllCols().Update(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return updateMilestoneCounters(e, m.ID)
|
||||
}
|
||||
|
||||
// updateMilestoneCounters calculates NumIssues, NumClosesIssues and Completeness
|
||||
func updateMilestoneCounters(e Engine, id int64) error {
|
||||
_, err := e.ID(id).
|
||||
SetExpr("num_issues", builder.Select("count(*)").From("issue").Where(
|
||||
builder.Eq{"milestone_id": m.ID},
|
||||
builder.Eq{"milestone_id": id},
|
||||
)).
|
||||
SetExpr("num_closed_issues", builder.Select("count(*)").From("issue").Where(
|
||||
builder.Eq{
|
||||
"milestone_id": m.ID,
|
||||
"milestone_id": id,
|
||||
"is_closed": true,
|
||||
},
|
||||
)).
|
||||
Update(m)
|
||||
Update(&Milestone{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func updateMilestoneCompleteness(e Engine, milestoneID int64) error {
|
||||
_, err := e.Exec("UPDATE `milestone` SET completeness=100*num_closed_issues/(CASE WHEN num_issues > 0 THEN num_issues ELSE 1 END) WHERE id=?",
|
||||
milestoneID,
|
||||
_, err = e.Exec("UPDATE `milestone` SET completeness=100*num_closed_issues/(CASE WHEN num_issues > 0 THEN num_issues ELSE 1 END) WHERE id=?",
|
||||
id,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -256,25 +264,15 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto
|
||||
}
|
||||
|
||||
if oldMilestoneID > 0 {
|
||||
if err := updateMilestoneTotalNum(e, oldMilestoneID); err != nil {
|
||||
if err := updateMilestoneCounters(e, oldMilestoneID); err != nil {
|
||||
return err
|
||||
}
|
||||
if issue.IsClosed {
|
||||
if err := updateMilestoneClosedNum(e, oldMilestoneID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if issue.MilestoneID > 0 {
|
||||
if err := updateMilestoneTotalNum(e, issue.MilestoneID); err != nil {
|
||||
if err := updateMilestoneCounters(e, issue.MilestoneID); err != nil {
|
||||
return err
|
||||
}
|
||||
if issue.IsClosed {
|
||||
if err := updateMilestoneClosedNum(e, issue.MilestoneID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if oldMilestoneID > 0 || issue.MilestoneID > 0 {
|
||||
@@ -558,29 +556,6 @@ func updateRepoMilestoneNum(e Engine, repoID int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func updateMilestoneTotalNum(e Engine, milestoneID int64) (err error) {
|
||||
if _, err = e.Exec("UPDATE `milestone` SET num_issues=(SELECT count(*) FROM issue WHERE milestone_id=?) WHERE id=?",
|
||||
milestoneID,
|
||||
milestoneID,
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return updateMilestoneCompleteness(e, milestoneID)
|
||||
}
|
||||
|
||||
func updateMilestoneClosedNum(e Engine, milestoneID int64) (err error) {
|
||||
if _, err = e.Exec("UPDATE `milestone` SET num_closed_issues=(SELECT count(*) FROM issue WHERE milestone_id=? AND is_closed=?) WHERE id=?",
|
||||
milestoneID,
|
||||
true,
|
||||
milestoneID,
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return updateMilestoneCompleteness(e, milestoneID)
|
||||
}
|
||||
|
||||
// _____ _ _ _____ _
|
||||
// |_ _| __ __ _ ___| | _____ __| |_ _(_)_ __ ___ ___ ___
|
||||
// | || '__/ _` |/ __| |/ / _ \/ _` | | | | | '_ ` _ \ / _ \/ __|
|
||||
|
||||
@@ -215,7 +215,7 @@ func TestChangeMilestoneStatus(t *testing.T) {
|
||||
CheckConsistencyFor(t, &Repository{ID: milestone.RepoID}, &Milestone{})
|
||||
}
|
||||
|
||||
func TestUpdateMilestoneClosedNum(t *testing.T) {
|
||||
func TestUpdateMilestoneCounters(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
issue := AssertExistsAndLoadBean(t, &Issue{MilestoneID: 1},
|
||||
"is_closed=0").(*Issue)
|
||||
@@ -224,14 +224,14 @@ func TestUpdateMilestoneClosedNum(t *testing.T) {
|
||||
issue.ClosedUnix = timeutil.TimeStampNow()
|
||||
_, err := x.ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, updateMilestoneClosedNum(x, issue.MilestoneID))
|
||||
assert.NoError(t, updateMilestoneCounters(x, issue.MilestoneID))
|
||||
CheckConsistencyFor(t, &Milestone{})
|
||||
|
||||
issue.IsClosed = false
|
||||
issue.ClosedUnix = 0
|
||||
_, err = x.ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, updateMilestoneClosedNum(x, issue.MilestoneID))
|
||||
assert.NoError(t, updateMilestoneCounters(x, issue.MilestoneID))
|
||||
CheckConsistencyFor(t, &Milestone{})
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ func (opts *ListOptions) setEnginePagination(e Engine) Engine {
|
||||
func (opts *ListOptions) GetStartEnd() (start, end int) {
|
||||
opts.setDefaultValues()
|
||||
start = (opts.Page - 1) * opts.PageSize
|
||||
end = start + opts.Page
|
||||
end = start + opts.PageSize
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,17 @@ var (
|
||||
_ convert.Conversion = &SSPIConfig{}
|
||||
)
|
||||
|
||||
// jsonUnmarshalIgnoreErroneousBOM - due to a bug in xorm (see https://gitea.com/xorm/xorm/pulls/1957) - it's
|
||||
// possible that a Blob may gain an unwanted prefix of 0xff 0xfe.
|
||||
func jsonUnmarshalIgnoreErroneousBOM(bs []byte, v interface{}) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
err := json.Unmarshal(bs, &v)
|
||||
if err != nil && len(bs) > 2 && bs[0] == 0xff && bs[1] == 0xfe {
|
||||
err = json.Unmarshal(bs[2:], &v)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// LDAPConfig holds configuration for LDAP login source.
|
||||
type LDAPConfig struct {
|
||||
*ldap.Source
|
||||
@@ -76,8 +87,7 @@ type LDAPConfig struct {
|
||||
|
||||
// FromDB fills up a LDAPConfig from serialized format.
|
||||
func (cfg *LDAPConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a LDAPConfig to a serialized format.
|
||||
@@ -104,8 +114,7 @@ type SMTPConfig struct {
|
||||
|
||||
// FromDB fills up an SMTPConfig from serialized format.
|
||||
func (cfg *SMTPConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
|
||||
}
|
||||
|
||||
// ToDB exports an SMTPConfig to a serialized format.
|
||||
@@ -122,8 +131,7 @@ type PAMConfig struct {
|
||||
|
||||
// FromDB fills up a PAMConfig from serialized format.
|
||||
func (cfg *PAMConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a PAMConfig to a serialized format.
|
||||
@@ -144,8 +152,7 @@ type OAuth2Config struct {
|
||||
|
||||
// FromDB fills up an OAuth2Config from serialized format.
|
||||
func (cfg *OAuth2Config) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
|
||||
}
|
||||
|
||||
// ToDB exports an SMTPConfig to a serialized format.
|
||||
@@ -165,8 +172,7 @@ type SSPIConfig struct {
|
||||
|
||||
// FromDB fills up an SSPIConfig from serialized format.
|
||||
func (cfg *SSPIConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
|
||||
}
|
||||
|
||||
// ToDB exports an SSPIConfig to a serialized format.
|
||||
|
||||
@@ -28,8 +28,7 @@ type UnitConfig struct{}
|
||||
|
||||
// FromDB fills up a UnitConfig from serialized format.
|
||||
func (cfg *UnitConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a UnitConfig to a serialized format.
|
||||
@@ -45,8 +44,7 @@ type ExternalWikiConfig struct {
|
||||
|
||||
// FromDB fills up a ExternalWikiConfig from serialized format.
|
||||
func (cfg *ExternalWikiConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a ExternalWikiConfig to a serialized format.
|
||||
@@ -64,8 +62,7 @@ type ExternalTrackerConfig struct {
|
||||
|
||||
// FromDB fills up a ExternalTrackerConfig from serialized format.
|
||||
func (cfg *ExternalTrackerConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a ExternalTrackerConfig to a serialized format.
|
||||
@@ -83,8 +80,7 @@ type IssuesConfig struct {
|
||||
|
||||
// FromDB fills up a IssuesConfig from serialized format.
|
||||
func (cfg *IssuesConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a IssuesConfig to a serialized format.
|
||||
@@ -106,8 +102,7 @@ type PullRequestsConfig struct {
|
||||
|
||||
// FromDB fills up a PullRequestsConfig from serialized format.
|
||||
func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Unmarshal(bs, &cfg)
|
||||
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
|
||||
}
|
||||
|
||||
// ToDB exports a PullRequestsConfig to a serialized format.
|
||||
|
||||
@@ -155,8 +155,8 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string]
|
||||
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
|
||||
Author: &api.CommitUser{
|
||||
Identity: api.Identity{
|
||||
Name: commit.Committer.Name,
|
||||
Email: commit.Committer.Email,
|
||||
Name: commit.Author.Name,
|
||||
Email: commit.Author.Email,
|
||||
},
|
||||
Date: commit.Author.When.Format(time.RFC3339),
|
||||
},
|
||||
|
||||
@@ -334,40 +334,37 @@ func (ctx *postProcessCtx) postProcess(rawHTML []byte) ([]byte, error) {
|
||||
_, _ = res.WriteString("</body></html>")
|
||||
|
||||
// parse the HTML
|
||||
nodes, err := html.ParseFragment(res, nil)
|
||||
node, err := html.Parse(res)
|
||||
if err != nil {
|
||||
return nil, &postProcessError{"invalid HTML", err}
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
ctx.visitNode(node, true)
|
||||
if node.Type == html.DocumentNode {
|
||||
node = node.FirstChild
|
||||
}
|
||||
|
||||
newNodes := make([]*html.Node, 0, len(nodes))
|
||||
ctx.visitNode(node, true)
|
||||
|
||||
nodes := make([]*html.Node, 0, 5)
|
||||
|
||||
for _, node := range nodes {
|
||||
if node.Data == "html" {
|
||||
node = node.FirstChild
|
||||
for node != nil && node.Data != "body" {
|
||||
node = node.NextSibling
|
||||
}
|
||||
}
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
if node != nil {
|
||||
if node.Data == "body" {
|
||||
child := node.FirstChild
|
||||
for child != nil {
|
||||
newNodes = append(newNodes, child)
|
||||
nodes = append(nodes, child)
|
||||
child = child.NextSibling
|
||||
}
|
||||
} else {
|
||||
newNodes = append(newNodes, node)
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
}
|
||||
|
||||
nodes = newNodes
|
||||
|
||||
// Create buffer in which the data will be placed again. We know that the
|
||||
// length will be at least that of res; to spare a few alloc+copy, we
|
||||
// reuse res, resetting its length to 0.
|
||||
@@ -404,7 +401,7 @@ func (ctx *postProcessCtx) visitNode(node *html.Node, visitText bool) {
|
||||
}
|
||||
case html.ElementNode:
|
||||
if node.Data == "img" {
|
||||
for _, attr := range node.Attr {
|
||||
for i, attr := range node.Attr {
|
||||
if attr.Key != "src" {
|
||||
continue
|
||||
}
|
||||
@@ -417,6 +414,7 @@ func (ctx *postProcessCtx) visitNode(node *html.Node, visitText bool) {
|
||||
|
||||
attr.Val = util.URLJoin(prefix, attr.Val)
|
||||
}
|
||||
node.Attr[i] = attr
|
||||
}
|
||||
} else if node.Data == "a" {
|
||||
visitText = false
|
||||
|
||||
@@ -384,6 +384,32 @@ func TestRender_ShortLinks(t *testing.T) {
|
||||
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`)
|
||||
}
|
||||
|
||||
func TestRender_RelativeImages(t *testing.T) {
|
||||
setting.AppURL = AppURL
|
||||
setting.AppSubURL = AppSubURL
|
||||
tree := util.URLJoin(AppSubURL, "src", "master")
|
||||
|
||||
test := func(input, expected, expectedWiki string) {
|
||||
buffer := markdown.RenderString(input, tree, localMetas)
|
||||
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
|
||||
buffer = markdown.RenderWiki([]byte(input), setting.AppSubURL, localMetas)
|
||||
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer))
|
||||
}
|
||||
|
||||
rawwiki := util.URLJoin(AppSubURL, "wiki", "raw")
|
||||
mediatree := util.URLJoin(AppSubURL, "media", "master")
|
||||
|
||||
test(
|
||||
`<img src="Link">`,
|
||||
`<img src="`+util.URLJoin(mediatree, "Link")+`"/>`,
|
||||
`<img src="`+util.URLJoin(rawwiki, "Link")+`"/>`)
|
||||
|
||||
test(
|
||||
`<img src="./icon.png">`,
|
||||
`<img src="`+util.URLJoin(mediatree, "icon.png")+`"/>`,
|
||||
`<img src="`+util.URLJoin(rawwiki, "icon.png")+`"/>`)
|
||||
}
|
||||
|
||||
func Test_ParseClusterFuzz(t *testing.T) {
|
||||
setting.AppURL = AppURL
|
||||
setting.AppSubURL = AppSubURL
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package references
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -14,6 +15,8 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup/mdstripper"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/yuin/goldmark/util"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -321,7 +324,7 @@ func FindRenderizableReferenceNumeric(content string, prOnly bool) (bool, *Rende
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
r := getCrossReference([]byte(content), match[2], match[3], false, prOnly)
|
||||
r := getCrossReference(util.StringToReadOnlyBytes(content), match[2], match[3], false, prOnly)
|
||||
if r == nil {
|
||||
return false, nil
|
||||
}
|
||||
@@ -465,17 +468,16 @@ func findAllIssueReferencesBytes(content []byte, links []string) []*rawReference
|
||||
}
|
||||
|
||||
func getCrossReference(content []byte, start, end int, fromLink bool, prOnly bool) *rawReference {
|
||||
refid := string(content[start:end])
|
||||
sep := strings.IndexAny(refid, "#!")
|
||||
sep := bytes.IndexAny(content[start:end], "#!")
|
||||
if sep < 0 {
|
||||
return nil
|
||||
}
|
||||
isPull := refid[sep] == '!'
|
||||
isPull := content[start+sep] == '!'
|
||||
if prOnly && !isPull {
|
||||
return nil
|
||||
}
|
||||
repo := refid[:sep]
|
||||
issue := refid[sep+1:]
|
||||
repo := string(content[start : start+sep])
|
||||
issue := string(content[start+sep+1 : end])
|
||||
index, err := strconv.ParseInt(issue, 10, 64)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
||||
@@ -986,10 +986,10 @@ func Routes() *web.Route {
|
||||
Delete(reqToken(), reqOrgMembership(), org.ConcealMember)
|
||||
})
|
||||
m.Group("/teams", func() {
|
||||
m.Combo("", reqToken()).Get(org.ListTeams).
|
||||
Post(reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
|
||||
m.Get("", org.ListTeams)
|
||||
m.Post("", reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
|
||||
m.Get("/search", org.SearchTeam)
|
||||
}, reqOrgMembership())
|
||||
}, reqToken(), reqOrgMembership())
|
||||
m.Group("/labels", func() {
|
||||
m.Get("", org.ListLabels)
|
||||
m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel)
|
||||
|
||||
@@ -17,7 +17,7 @@ func GetUserByParamsName(ctx *context.APIContext, name string) *models.User {
|
||||
user, err := models.GetUserByName(username)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
if redirectUserID, err := models.LookupUserRedirect(username); err == nil {
|
||||
if redirectUserID, err2 := models.LookupUserRedirect(username); err2 == nil {
|
||||
context.RedirectToUser(ctx.Context, username, redirectUserID)
|
||||
} else {
|
||||
ctx.NotFound("GetUserByName", err)
|
||||
|
||||
@@ -193,16 +193,17 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
|
||||
}
|
||||
|
||||
commits = repo_module.ListToPushCommits(l)
|
||||
|
||||
if err := repofiles.UpdateIssuesCommit(pusher, repo, commits.Commits, refName); err != nil {
|
||||
log.Error("updateIssuesCommit: %v", err)
|
||||
}
|
||||
|
||||
if len(commits.Commits) > setting.UI.FeedMaxCommitNum {
|
||||
commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
|
||||
}
|
||||
commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
|
||||
notification.NotifyPushCommits(pusher, repo, opts, commits)
|
||||
|
||||
if err := repofiles.UpdateIssuesCommit(pusher, repo, commits.Commits, refName); err != nil {
|
||||
log.Error("updateIssuesCommit: %v", err)
|
||||
}
|
||||
|
||||
if err = models.RemoveDeletedBranch(repo.ID, branch); err != nil {
|
||||
log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, branch, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user