From 6e7d28cf3aef9e91c435f841ec217bff5c750b87 Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 16 Dec 2021 17:40:18 +0000 Subject: [PATCH] Prevent double decoding of % in url params (#17997) There was an unfortunate regression in #14293 which has led to the double decoding of url parameter elements if they contain a '%'. This is due to an issue with the way chi decodes its RoutePath. In detail the problem lies in mux.go where the routeHTTP path uses the URL.RawPath or even the URL.Path instead of the escaped path to do routing. This PR simply forcibly sets the routePath to that of the EscapedPath. Fix #17938 Signed-off-by: Andrew Thornton --- .../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 | 36 ++++++++++++++++++ modules/context/context.go | 4 ++ 12 files changed, 41 insertions(+), 1 deletion(-) 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 00dd05db8..c2850d4c4 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 cf6261dff..71d0ee3cb 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" @@ -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 88cf498f8..94e1f6cff 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -609,6 +609,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(),