@@ -463,6 +463,40 @@ static public function isProxyTrusted()
463
463
return self ::$ trustProxy ;
464
464
}
465
465
466
+ /**
467
+ * Normalizes a query string.
468
+ *
469
+ * It builds a normalized query string, where keys/value pairs are alphabetized
470
+ * and have consistent escaping.
471
+ *
472
+ * @param string $qs Query string
473
+ *
474
+ * @return string|null A normalized query string for the Request
475
+ */
476
+ static public function normalizeQueryString ($ qs = null )
477
+ {
478
+ if (!$ qs ) {
479
+ return null ;
480
+ }
481
+
482
+ $ parts = array ();
483
+ $ order = array ();
484
+
485
+ foreach (explode ('& ' , $ qs ) as $ segment ) {
486
+ if (false === strpos ($ segment , '= ' )) {
487
+ $ parts [] = $ segment ;
488
+ $ order [] = $ segment ;
489
+ } else {
490
+ $ tmp = explode ('= ' , rawurldecode ($ segment ), 2 );
491
+ $ parts [] = rawurlencode ($ tmp [0 ]).'= ' .rawurlencode ($ tmp [1 ]);
492
+ $ order [] = $ tmp [0 ];
493
+ }
494
+ }
495
+ array_multisort ($ order , SORT_ASC , $ parts );
496
+
497
+ return implode ('& ' , $ parts );
498
+ }
499
+
466
500
/**
467
501
* Gets a "parameter" value.
468
502
*
@@ -809,26 +843,7 @@ public function getUriForPath($path)
809
843
*/
810
844
public function getQueryString ()
811
845
{
812
- if (!$ qs = $ this ->server ->get ('QUERY_STRING ' )) {
813
- return null ;
814
- }
815
-
816
- $ parts = array ();
817
- $ order = array ();
818
-
819
- foreach (explode ('& ' , $ qs ) as $ segment ) {
820
- if (false === strpos ($ segment , '= ' )) {
821
- $ parts [] = $ segment ;
822
- $ order [] = $ segment ;
823
- } else {
824
- $ tmp = explode ('= ' , rawurldecode ($ segment ), 2 );
825
- $ parts [] = rawurlencode ($ tmp [0 ]).'= ' .rawurlencode ($ tmp [1 ]);
826
- $ order [] = $ tmp [0 ];
827
- }
828
- }
829
- array_multisort ($ order , SORT_ASC , $ parts );
830
-
831
- return implode ('& ' , $ parts );
846
+ return static ::normalizeQueryString ($ this ->server ->get ('QUERY_STRING ' ));
832
847
}
833
848
834
849
/**
0 commit comments