@@ -65,19 +65,39 @@ public function handle(Request $request, Closure $next, string ...$guards): Resp
6565
6666 private function redirectWithPreservedParams ($ to , $ status )
6767 {
68- $ preserveKeys = [];
68+ $ stripKeys = [];
6969 foreach ((new Data ('query-strings ' ))->all () as $ item ) {
70- if (!( $ item ['strip ' ] ?? false ) ) {
71- $ preserveKeys [] = $ item ['query_string ' ];
70+ if ($ item ['strip ' ] ?? false ) {
71+ $ stripKeys [] = strtolower ( $ item ['query_string ' ]) ;
7272 }
7373 }
7474
75+ // Parse raw query string to handle double-encoding and duplicates
76+ $ rawQueryString = request ()->getQueryString ();
7577 $ filteredStrings = [];
76- foreach (request ()->all () as $ key => $ value ) {
77- if (!in_array ($ key , $ preserveKeys )) {
78- continue ;
78+ $ seenKeys = [];
79+
80+ if ($ rawQueryString ) {
81+ // Decode the query string recursively to handle multiple levels of encoding
82+ $ decodedQueryString = $ rawQueryString ;
83+ $ previousQueryString = '' ;
84+
85+ // Keep decoding until no more changes occur (handles double/triple encoding)
86+ while ($ decodedQueryString !== $ previousQueryString ) {
87+ $ previousQueryString = $ decodedQueryString ;
88+ $ decodedQueryString = urldecode ($ decodedQueryString );
89+ }
90+
91+ parse_str ($ decodedQueryString , $ parsedParams );
92+
93+ foreach ($ parsedParams as $ key => $ value ) {
94+ $ normalizedKey = strtolower ($ key );
95+ // Strip only parameters marked with strip:true, preserve all others
96+ if (!in_array ($ normalizedKey , $ stripKeys ) && !isset ($ seenKeys [$ normalizedKey ])) {
97+ $ seenKeys [$ normalizedKey ] = true ;
98+ $ filteredStrings [] = sprintf ("%s=%s " , urlencode ($ key ), urlencode ($ value ));
99+ }
79100 }
80- $ filteredStrings [] = sprintf ( "%s=%s " , $ key , $ value );
81101 }
82102
83103 if ($ filteredStrings ) {
0 commit comments