Introduce ctx.PathParamRaw to avoid incorrect unescaping (#26392)

Fix #26389

And complete an old TODO: `ctx.Params does un-escaping,..., which is
incorrect.`
This commit is contained in:
wxiaoguang 2023-08-09 14:57:45 +08:00 committed by GitHub
parent 906e253d5e
commit c2e0143bfe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 17 deletions

View file

@ -22,15 +22,16 @@ import (
// - "/wiki/100%25+Free"
// - "/wiki/2000-01-02+meeting.-"
// - If a segment has a suffix "DashMarker(.-)", it means that there is no dash-space conversion for this segment.
// - If a WebPath is a "*.md" pattern, then use it directly as GitPath, to make users can access the raw file.
// - If a WebPath is a "*.md" pattern, then use the unescaped value directly as GitPath, to make users can access the raw file.
// * Git Path (only space doesn't need to be escaped):
// - "/.wiki.git/Home-Page.md"
// - "/.wiki.git/100%25 Free.md"
// - "/.wiki.git/2000-01-02 meeting.-.md"
// TODO: support subdirectory in the future
//
// Although this package now has the ablity to support subdirectory, but the route package doesn't:
// Although this package now has the ability to support subdirectory, but the route package doesn't:
// * Double-escaping problem: the URL "/wiki/abc%2Fdef" becomes "/wiki/abc/def" by ctx.Params, which is incorrect
// * This problem should have been 99% fixed, but it needs more tests.
// * The old wiki code's behavior is always using %2F, instead of subdirectory, so there are a lot of legacy "%2F" files in user wikis.
type WebPath string
@ -91,7 +92,8 @@ func WebPathSegments(s WebPath) []string {
func WebPathToGitPath(s WebPath) string {
if strings.HasSuffix(string(s), ".md") {
return string(s)
ret, _ := url.PathUnescape(string(s))
return util.PathJoinRelX(ret)
}
a := strings.Split(string(s), "/")
@ -124,7 +126,10 @@ func GitPathToWebPath(s string) (wp WebPath, err error) {
func WebPathToUserTitle(s WebPath) (dir, display string) {
dir = path.Dir(string(s))
display = path.Base(string(s))
display = strings.TrimSuffix(display, ".md")
if strings.HasSuffix(display, ".md") {
display = strings.TrimSuffix(display, ".md")
display, _ = url.PathUnescape(display)
}
display, _ = unescapeSegment(display)
return dir, display
}
@ -141,8 +146,7 @@ func WebPathFromRequest(s string) WebPath {
}
func UserTitleToWebPath(base, title string) WebPath {
// TODO: ctx.Params does un-escaping, so the URL "/wiki/abc%2Fdef" becomes "wiki path = `abc/def`", which is incorrect.
// And the old wiki code's behavior is always using %2F, instead of subdirectory.
// TODO: no support for subdirectory, because the old wiki code's behavior is always using %2F, instead of subdirectory.
// So we do not add the support for writing slashes in title at the moment.
title = strings.TrimSpace(title)
title = util.PathJoinRelX(base, escapeSegToWeb(title, false))

View file

@ -59,6 +59,7 @@ func TestWebPathToDisplayName(t *testing.T) {
{"name with / slash", "name-with %2F slash"},
{"name with % percent", "name-with %25 percent"},
{"2000-01-02 meeting", "2000-01-02+meeting.-.md"},
{"a b", "a%20b.md"},
} {
_, displayName := WebPathToUserTitle(test.WebPath)
assert.EqualValues(t, test.Expected, displayName)
@ -73,7 +74,8 @@ func TestWebPathToGitPath(t *testing.T) {
for _, test := range []test{
{"wiki-name.md", "wiki%20name"},
{"wiki-name.md", "wiki+name"},
{"wiki%20name.md", "wiki%20name.md"},
{"wiki name.md", "wiki%20name.md"},
{"wiki%20name.md", "wiki%2520name.md"},
{"2000-01-02-meeting.md", "2000-01-02+meeting"},
{"2000-01-02 meeting.-.md", "2000-01-02%20meeting.-"},
} {