Skip to content

Commit 4a11446

Browse files
committed
fix
1 parent 6f7cd94 commit 4a11446

File tree

3 files changed

+96
-60
lines changed

3 files changed

+96
-60
lines changed

modules/markup/html.go

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ var (
5454
shortLinkPattern = regexp.MustCompile(`\[\[(.*?)\]\](\w*)`)
5555

5656
// anyHashPattern splits url containing SHA into parts
57-
anyHashPattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40,64})(/[-+~_%.a-zA-Z0-9/]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
57+
anyHashPattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40,64})(/[-+~%./\w]+)?(\?[-+~%.\w&=]+)?(#[-+~%.\w]+)?`)
5858

5959
// comparePattern matches "http://domain/org/repo/compare/COMMIT1...COMMIT2#hash"
6060
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{7,64})(\.\.\.?)([0-9a-f]{7,64})?(#[-+~_%.a-zA-Z0-9]+)?`)
@@ -963,57 +963,63 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) {
963963
}
964964
}
965965

966-
// fullHashPatternProcessor renders SHA containing URLs
967-
func fullHashPatternProcessor(ctx *RenderContext, node *html.Node) {
968-
if ctx.Metas == nil {
969-
return
970-
}
971-
972-
next := node.NextSibling
973-
for node != nil && node != next {
974-
m := anyHashPattern.FindStringSubmatchIndex(node.Data)
975-
if m == nil {
976-
return
977-
}
966+
type anyHashPatternResult struct {
967+
PosStart int
968+
PosEnd int
969+
FullURL string
970+
CommitID string
971+
SubPath string
972+
QueryHash string
973+
}
978974

979-
urlFull := node.Data[m[0]:m[1]]
980-
text := base.ShortSha(node.Data[m[2]:m[3]])
975+
func anyHashPatternExtract(s string) (ret anyHashPatternResult, ok bool) {
976+
m := anyHashPattern.FindStringSubmatchIndex(s)
977+
if m == nil {
978+
return ret, false
979+
}
981980

982-
// 3rd capture group matches a optional path
983-
subpath := ""
984-
if m[5] > 0 {
985-
subpath = node.Data[m[4]:m[5]]
981+
ret.PosStart, ret.PosEnd = m[0], m[1]
982+
ret.FullURL = s[ret.PosStart:ret.PosEnd]
983+
if strings.HasSuffix(ret.FullURL, ".") {
984+
// if url ends in '.', it's very likely that it is not part of the actual url but used to finish a sentence.
985+
ret.PosEnd--
986+
ret.FullURL = ret.FullURL[:len(ret.FullURL)-1]
987+
for i := 0; i < len(m); i++ {
988+
m[i] = min(m[i], ret.PosEnd)
986989
}
990+
}
987991

988-
// 4th capture group matches a optional url hash
989-
hash := ""
990-
if m[7] > 0 {
991-
hash = node.Data[m[6]:m[7]][1:]
992-
}
992+
ret.CommitID = s[m[2]:m[3]]
993+
if m[5] > 0 {
994+
ret.SubPath = s[m[4]:m[5]]
995+
}
993996

994-
start := m[0]
995-
end := m[1]
997+
lastStart, lastEnd := m[len(m)-2], m[len(m)-1]
998+
if lastEnd > 0 {
999+
ret.QueryHash = s[lastStart:lastEnd][1:]
1000+
}
1001+
return ret, true
1002+
}
9961003

997-
// If url ends in '.', it's very likely that it is not part of the
998-
// actual url but used to finish a sentence.
999-
if strings.HasSuffix(urlFull, ".") {
1000-
end--
1001-
urlFull = urlFull[:len(urlFull)-1]
1002-
if hash != "" {
1003-
hash = hash[:len(hash)-1]
1004-
} else if subpath != "" {
1005-
subpath = subpath[:len(subpath)-1]
1006-
}
1004+
// fullHashPatternProcessor renders SHA containing URLs
1005+
func fullHashPatternProcessor(ctx *RenderContext, node *html.Node) {
1006+
if ctx.Metas == nil {
1007+
return
1008+
}
1009+
for node != nil {
1010+
ret, ok := anyHashPatternExtract(node.Data)
1011+
if !ok {
1012+
node = node.NextSibling
1013+
continue
10071014
}
1008-
1009-
if subpath != "" {
1010-
text += subpath
1015+
text := base.ShortSha(ret.CommitID)
1016+
if ret.SubPath != "" {
1017+
text += ret.SubPath
10111018
}
1012-
1013-
if hash != "" {
1014-
text += " (" + hash + ")"
1019+
if ret.QueryHash != "" {
1020+
text += " (" + ret.QueryHash + ")"
10151021
}
1016-
replaceContent(node, start, end, createCodeLink(urlFull, text, "commit"))
1022+
replaceContent(node, ret.PosStart, ret.PosEnd, createCodeLink(ret.FullURL, text, "commit"))
10171023
node = node.NextSibling.NextSibling
10181024
}
10191025
}

modules/markup/html_internal_test.go

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -399,36 +399,61 @@ func TestRegExp_sha1CurrentPattern(t *testing.T) {
399399
}
400400

401401
func TestRegExp_anySHA1Pattern(t *testing.T) {
402-
testCases := map[string][]string{
402+
testCases := map[string]anyHashPatternResult{
403403
"https://github.com/jquery/jquery/blob/a644101ed04d0beacea864ce805e0c4f86ba1cd1/test/unit/event.js#L2703": {
404-
"a644101ed04d0beacea864ce805e0c4f86ba1cd1",
405-
"/test/unit/event.js",
406-
"#L2703",
404+
CommitID: "a644101ed04d0beacea864ce805e0c4f86ba1cd1",
405+
SubPath: "/test/unit/event.js",
406+
QueryHash: "L2703",
407407
},
408408
"https://github.com/jquery/jquery/blob/a644101ed04d0beacea864ce805e0c4f86ba1cd1/test/unit/event.js": {
409-
"a644101ed04d0beacea864ce805e0c4f86ba1cd1",
410-
"/test/unit/event.js",
411-
"",
409+
CommitID: "a644101ed04d0beacea864ce805e0c4f86ba1cd1",
410+
SubPath: "/test/unit/event.js",
412411
},
413412
"https://github.com/jquery/jquery/commit/0705be475092aede1eddae01319ec931fb9c65fc": {
414-
"0705be475092aede1eddae01319ec931fb9c65fc",
415-
"",
416-
"",
413+
CommitID: "0705be475092aede1eddae01319ec931fb9c65fc",
417414
},
418415
"https://github.com/jquery/jquery/tree/0705be475092aede1eddae01319ec931fb9c65fc/src": {
419-
"0705be475092aede1eddae01319ec931fb9c65fc",
420-
"/src",
421-
"",
416+
CommitID: "0705be475092aede1eddae01319ec931fb9c65fc",
417+
SubPath: "/src",
422418
},
423419
"https://try.gogs.io/gogs/gogs/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2": {
424-
"d8a994ef243349f321568f9e36d5c3f444b99cae",
425-
"",
426-
"#diff-2",
420+
CommitID: "d8a994ef243349f321568f9e36d5c3f444b99cae",
421+
QueryHash: "diff-2",
422+
},
423+
"non-url": {},
424+
"http://a/b/c/d/e/1234567812345678123456781234567812345678123456781234567812345678?a=b#L1-L2": {
425+
CommitID: "1234567812345678123456781234567812345678123456781234567812345678",
426+
QueryHash: "L1-L2",
427+
},
428+
"http://a/b/c/d/e/1234567812345678123456781234567812345678123456781234567812345678.": {
429+
CommitID: "1234567812345678123456781234567812345678123456781234567812345678",
430+
},
431+
"http://a/b/c/d/e/1234567812345678123456781234567812345678123456781234567812345678/sub.": {
432+
CommitID: "1234567812345678123456781234567812345678123456781234567812345678",
433+
SubPath: "/sub",
434+
},
435+
"http://a/b/c/d/e/1234567812345678123456781234567812345678123456781234567812345678?a=b.": {
436+
CommitID: "1234567812345678123456781234567812345678123456781234567812345678",
437+
},
438+
"http://a/b/c/d/e/1234567812345678123456781234567812345678123456781234567812345678?a=b&c=d": {
439+
CommitID: "1234567812345678123456781234567812345678123456781234567812345678",
440+
},
441+
"http://a/b/c/d/e/1234567812345678123456781234567812345678123456781234567812345678#hash.": {
442+
CommitID: "1234567812345678123456781234567812345678123456781234567812345678",
443+
QueryHash: "hash",
427444
},
428445
}
429446

430447
for k, v := range testCases {
431-
assert.Equal(t, anyHashPattern.FindStringSubmatch(k)[1:], v)
448+
ret, ok := anyHashPatternExtract(k)
449+
if v.CommitID == "" {
450+
assert.False(t, ok)
451+
} else {
452+
assert.EqualValues(t, strings.TrimSuffix(k, "."), ret.FullURL)
453+
assert.EqualValues(t, v.CommitID, ret.CommitID)
454+
assert.EqualValues(t, v.SubPath, ret.SubPath)
455+
assert.EqualValues(t, v.QueryHash, ret.QueryHash)
456+
}
432457
}
433458
}
434459

modules/markup/html_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ func TestRender_CrossReferences(t *testing.T) {
124124
test(
125125
util.URLJoin(markup.TestAppURL, "gogitea", "some-repo-name", "issues", "12345"),
126126
`<p><a href="`+util.URLJoin(markup.TestAppURL, "gogitea", "some-repo-name", "issues", "12345")+`" class="ref-issue" rel="nofollow">gogitea/some-repo-name#12345</a></p>`)
127+
128+
inputURL := "https://host/a/b/commit/0123456789012345678901234567890123456789/foo.txt?a=b#L2-L3"
129+
test(
130+
inputURL,
131+
`<p><a href="`+inputURL+`" rel="nofollow"><code>0123456789/foo.txt (L2-L3)</code></a></p>`)
127132
}
128133

129134
func TestMisc_IsSameDomain(t *testing.T) {

0 commit comments

Comments
 (0)