@@ -1211,12 +1211,13 @@ func TestStateBookkeepingErrorBranches(t *testing.T) {
12111211
12121212func TestVerifyChallengePage (t * testing.T ) {
12131213 tests := []struct {
1214- name string
1215- provider string
1216- formValues map [string ]string
1217- mockResponse string
1218- expectedStatus int
1219- shouldSetCache bool
1214+ name string
1215+ provider string
1216+ formValues map [string ]string
1217+ mockResponse string
1218+ expectedStatus int
1219+ shouldSetCache bool
1220+ expectedLocation string
12201221 }{
12211222 {
12221223 name : "Missing captcha response" ,
@@ -1232,19 +1233,33 @@ func TestVerifyChallengePage(t *testing.T) {
12321233 "cf-turnstile-response" : "valid-token" ,
12331234 "destination" : "%2Fhome" ,
12341235 },
1235- mockResponse : `{"success":true}` ,
1236- expectedStatus : http .StatusFound ,
1237- shouldSetCache : true ,
1236+ mockResponse : `{"success":true}` ,
1237+ expectedStatus : http .StatusFound ,
1238+ shouldSetCache : true ,
1239+ expectedLocation : "/home" ,
1240+ },
1241+ {
1242+ name : "Successful verification preserves literal plus" ,
1243+ provider : "turnstile" ,
1244+ formValues : map [string ]string {
1245+ "cf-turnstile-response" : "valid-token" ,
1246+ "destination" : "/Chrome%20+%20MariaDB%20" ,
1247+ },
1248+ mockResponse : `{"success":true}` ,
1249+ expectedStatus : http .StatusFound ,
1250+ shouldSetCache : true ,
1251+ expectedLocation : "/Chrome%20+%20MariaDB%20" ,
12381252 },
12391253 {
12401254 name : "Successful verification without destination" ,
12411255 provider : "recaptcha" ,
12421256 formValues : map [string ]string {
12431257 "g-recaptcha-response" : "valid-token" ,
12441258 },
1245- mockResponse : `{"success":true}` ,
1246- expectedStatus : http .StatusFound ,
1247- shouldSetCache : true ,
1259+ mockResponse : `{"success":true}` ,
1260+ expectedStatus : http .StatusFound ,
1261+ shouldSetCache : true ,
1262+ expectedLocation : "/" ,
12481263 },
12491264 {
12501265 name : "Failed verification" ,
@@ -1263,9 +1278,10 @@ func TestVerifyChallengePage(t *testing.T) {
12631278 "cf-turnstile-response" : "valid-token" ,
12641279 "destination" : "%ZZ" ,
12651280 },
1266- mockResponse : `{"success":true}` ,
1267- expectedStatus : http .StatusFound ,
1268- shouldSetCache : true ,
1281+ mockResponse : `{"success":true}` ,
1282+ expectedStatus : http .StatusFound ,
1283+ shouldSetCache : true ,
1284+ expectedLocation : "/" ,
12691285 },
12701286 }
12711287
@@ -1310,6 +1326,10 @@ func TestVerifyChallengePage(t *testing.T) {
13101326 if found != tt .shouldSetCache {
13111327 t .Errorf ("Expected cache set=%v, got=%v" , tt .shouldSetCache , found )
13121328 }
1329+
1330+ if tt .expectedLocation != "" && rr .Header ().Get ("Location" ) != tt .expectedLocation {
1331+ t .Errorf ("Expected Location %q, got %q" , tt .expectedLocation , rr .Header ().Get ("Location" ))
1332+ }
13131333 })
13141334 }
13151335}
@@ -2106,6 +2126,8 @@ func TestNormalizeDestination(t *testing.T) {
21062126 {name : "empty" , destination : "" , want : "/" },
21072127 {name : "decoded local path" , destination : "/home?foo=bar" , want : "/home?foo=bar" },
21082128 {name : "encoded local path" , destination : "%2Fhome%3Ffoo%3Dbar" , want : "/home?foo=bar" },
2129+ {name : "decoded path with literal plus" , destination : "/Chrome%20+%20MariaDB%20" , want : "/Chrome%20+%20MariaDB%20" },
2130+ {name : "encoded path with literal plus" , destination : "%2FChrome%2520%2B%2520MariaDB%2520" , want : "/Chrome%20+%20MariaDB%20" },
21092131 {name : "absolute url" , destination : "https://evil.com/phish" , want : "/" },
21102132 {name : "protocol relative url" , destination : "//evil.com/phish" , want : "/" },
21112133 {name : "relative path" , destination : "home" , want : "/" },
0 commit comments