From 3a77465e4ed252f5d92da12321613328b30b941c Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 16 Dec 2021 23:03:20 +0000 Subject: [PATCH] Prevent double decoding of % in url params (#17997) (#18001) --- .../4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a | Bin 0 -> 40 bytes .../50/4d9fe743979d4e9785a25a363c7007293f0838 | Bin 0 -> 40 bytes .../59/e2c41e8f5140bb0182acebec17c8ad9831cc62 | Bin 0 -> 847 bytes .../64/89894ad11093fdc49c0ed857d80682344a7264 | Bin 0 -> 39 bytes .../84/7c6d93c6860dd377651245711b7fbcd34a18d4 | Bin 0 -> 41 bytes .../9b/9cc8f558d1c4f815592496fa24308ba2a9c824 | Bin 0 -> 47 bytes .../a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad | Bin 0 -> 394 bytes .../c7/85b65bf16928b58567cb23669125c0ccd25a4f | Bin 0 -> 44 bytes .../e9/63733b8a355cf860c465b4af7b236a6ef08783 | Bin 0 -> 47 bytes .../utf8.git/refs/heads/Plus+Is+Not+Space | 2 +- integrations/nonascii_branches_test.go | 46 ++++++++++++++++-- modules/context/context.go | 4 ++ modules/context/repo.go | 2 +- 13 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/9b/9cc8f558d1c4f815592496fa24308ba2a9c824 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/e9/63733b8a355cf860c465b4af7b236a6ef08783 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a b/integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a new file mode 100644 index 0000000000000000000000000000000000000000..17b3104773bbfb8ccdb5084cd6dda8a5ec794098 GIT binary patch literal 40 ycmV+@0N4L`0ZYosPf{>4VJObXFU?6&$jdKLNJ>?(&n!-~Ps_|nlhEoiLBnXFNksc<6)~1Zn7b`1t8Qd&I=Btb+4C072*vod5s; literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 new file mode 100644 index 0000000000000000000000000000000000000000..736a24227c153003864cb1b41e751db5af19f495 GIT binary patch literal 847 zcmV-V1F-yf0d14X&Z9^Wgy+mt)E!N;nnmg!HLJ~H3b*{pZE#8vBlre z(ES4#fs+MB;AI|=^hd;per{Xv1e89T@CKsKf_@o#@EuMIEB-{VUts#J$IBn4i?Nui z0{s22RAX;>z~B2IwDz77#b@I;CjbGezD-`MUl`0(RQ??VYon<|1+dJJzJ4vt7j1R-e!YFkQ zU$TFYkIa!N$O5gob;AUBCCn&0O;l$G%*YnAb37+Fi|k{u%-5{P<3j4LDBhcK>#OMr-tw}Zcv6-$9v*tZ#VH8%74c31t4hLsNwl)NKV)s@1|Mi>8U zAIOMDeCDEC5nuKM=uVAseVsLm@@*=S9Fe~Y1HjTO8Ei7kXo&;$z$ z6{vYE$x)N0XdfSJlId;g{J1W)CtP)vjGf7oB2G^a#hlH_md&ZeLHP_cRCj~V%V`EEeTT{)P`<4^EgMpDXPYUZj*Dn=sI)Tb%cjx{2H4Tg=H#B)wmUPvmDb&Ja{W>5cgZ0e;xjl_UPkjN$2j ZN(`Z78R&)y1H4u($g395#4n|VR?zITsw@Bi literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 new file mode 100644 index 0000000000000000000000000000000000000000..87e198aa9ca2e9f95e3fa41a231e50e697b131af GIT binary patch literal 39 vcmb2lZ0;dW9HS!N? literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 new file mode 100644 index 0000000000000000000000000000000000000000..ffea321c19db661925c77ef5367155c13ba0b308 GIT binary patch literal 41 xcmbQM8W(dj1ELH%b!qUu=RE5Mmh19al9EH5Z+|(3>w9K4TE&v;G F4X_eV7Igps literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad b/integrations/gitea-repositories-meta/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad new file mode 100644 index 0000000000000000000000000000000000000000..9655a74c8321a8c3d9cf08111c6f1b320bf641ba GIT binary patch literal 394 zcmV;50d@X(0V^p=O;s>4F<~$?FfcPQQBYMiGBq;I%}mcI$;&S($Vsd$PtD0;Na^hK zx+pOD?~yrtH^OhQHJNx7rNDF;nHsxg76Vl$7M7+Kmt^MW0nIRWV|bZdY~5uV^CRI% z>X!A@%2|0I+M8i|KsxLb^HP)((=u~X8GI7&a#habFnC^f|JiZ>8k5;4o@qgq8XBnT z<)$#S)Z|V+*2a6eJXOfGP`ZB4WiN>e(|)NKbT3+YLItYq o!jcOcF6_Lp8)VuSrvK>&HjBwvcHI6Z(U-^jDg19K0DZ-*LE@RcF8}}l literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f b/integrations/gitea-repositories-meta/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f new file mode 100644 index 0000000000000000000000000000000000000000..2cc606b7f2630a7bfe9e14c3a2eb3df81e880e31 GIT binary patch literal 44 zcmV+{0Mq|?0ZYosPf{>8U`ELKR%%t=+q&&#P)$Ve;(GEx8WbiCe$SN%^QOGRLQ!i0SR46P>EiTE-&r`@vEXwBM0s#Gp F48*|e6Wjm* literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space b/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space index 00dd05db8c..c2850d4c4d 100644 --- a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space +++ b/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space @@ -1 +1 @@ -3a810dbf6b96afaa8c5f69a8b6ec1dabfca7368b +59e2c41e8f5140bb0182acebec17c8ad9831cc62 diff --git a/integrations/nonascii_branches_test.go b/integrations/nonascii_branches_test.go index 22d71e6ee2..1aab16fa3e 100644 --- a/integrations/nonascii_branches_test.go +++ b/integrations/nonascii_branches_test.go @@ -6,6 +6,7 @@ package integrations import ( "net/http" + "net/url" "path" "testing" @@ -83,7 +84,7 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "Plus+Is+Not+Space/Файл.md", - to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", + to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", status: http.StatusOK, }, { @@ -114,7 +115,7 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "タグ/ファイル.md", - to: "tag/%e3%82%bf%e3%82%b0/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab.md", + to: "tag/%e3%82%bf%e3%82%b0/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md", status: http.StatusOK, }, // Files @@ -125,12 +126,12 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "Файл.md", - to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", + to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", status: http.StatusOK, }, { from: "ファイル.md", - to: "branch/Plus+Is+Not+Space/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab.md", + to: "branch/Plus+Is+Not+Space/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md", status: http.StatusNotFound, // it's not on default branch }, // Same but url-encoded (few tests) @@ -146,7 +147,7 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "%D0%A4%D0%B0%D0%B9%D0%BB.md", - to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", + to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", status: http.StatusOK, }, { @@ -159,6 +160,41 @@ func TestNonasciiBranches(t *testing.T) { to: "tag/%d0%81/%e4%ba%ba", status: http.StatusOK, }, + { + from: "Plus+Is+Not+Space/%25%252525mightnotplaywell", + to: "branch/Plus+Is+Not+Space/%25%252525mightnotplaywell", + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/%25253Fisnotaquestion%25253F", + to: "branch/Plus+Is+Not+Space/%25253Fisnotaquestion%25253F", + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"), + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/10%25.md", + to: "branch/Plus+Is+Not+Space/10%25.md", + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"), + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"), + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"), + status: http.StatusOK, + }, } defer prepareTestEnv(t)() diff --git a/modules/context/context.go b/modules/context/context.go index 568865d90e..82771b0c24 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -669,6 +669,10 @@ func Contexter() func(next http.Handler) http.Handler { var locale = middleware.Locale(resp, req) var startTime = time.Now() var link = setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/") + + chiCtx := chi.RouteContext(req.Context()) + chiCtx.RoutePath = req.URL.EscapedPath() + var ctx = Context{ Resp: NewResponse(resp), Cache: mc.GetCache(), diff --git a/modules/context/repo.go b/modules/context/repo.go index 12943ae37f..0f78ff429b 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -833,7 +833,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context setting.AppSubURL, strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*")), ctx.Repo.BranchNameSubURL(), - ctx.Repo.TreePath)) + util.PathEscapeSegments(ctx.Repo.TreePath))) return } }