@@ -336,13 +336,30 @@ function svn_utils_add_sort_criteria($criteria_list, $order, $msort)
336336 return (join (', ' , $ arr ));
337337}
338338
339- // Transform criteria list to SQL query (+ means ascending
340- // - is descending)
341- function svn_utils_criteria_list_to_query ($ criteria_list )
339+ /**
340+ * @psalm-return array<array{order:"ASC"|"DESC", column: "revision"|"commit_id"|"description"|"date"|"whoid"}>
341+ */
342+ function svn_utils_criteria_list_to_query (string $ criteria_list ): array
342343{
343- $ criteria_list = str_replace ('> ' , ' ASC ' , $ criteria_list );
344- $ criteria_list = str_replace ('< ' , ' DESC ' , $ criteria_list );
345- return $ criteria_list ;
344+ $ order_list = [];
345+
346+ foreach (explode (', ' , $ criteria_list ) as $ criteria ) {
347+ if (preg_match ('/^(?<column>[a-z]+)(?<order>[<>]?)$/ ' , $ criteria , $ matches ) === 1 ) {
348+ $ column = $ matches ['column ' ];
349+ if (! in_array ($ column , ['revision ' , 'commit_id ' , 'description ' , 'date ' , 'whoid ' ], true )) {
350+ continue ;
351+ }
352+
353+ $ order = 'ASC ' ;
354+ if ($ matches ['order ' ] === '< ' ) {
355+ $ order = 'DESC ' ;
356+ }
357+
358+ $ order_list [] = ['order ' => $ order , 'column ' => $ column ];
359+ }
360+ }
361+
362+ return $ order_list ;
346363}
347364
348365// Transform criteria list to readable text statement
@@ -353,13 +370,15 @@ function svn_utils_criteria_list_to_text($criteria_list, $url)
353370 $ morder = '' ;
354371 $ arr = explode (', ' , $ criteria_list );
355372
373+ $ purifier = Codendi_HTMLPurifier::instance ();
374+
356375 foreach ($ arr as $ crit ) {
357376 $ morder .= ($ morder ? ", " . $ crit : $ crit );
358377 $ attr = str_replace ('> ' , '' , $ crit );
359378 $ attr = str_replace ('< ' , '' , $ attr );
360379
361- $ arr_text [] = '<a href=" ' . $ url . '&morder= ' . $ morder . '#results"> ' .
362- svn_utils_field_get_label ($ attr ) . '</a><img src=" ' . util_get_dir_image_theme () .
380+ $ arr_text [] = '<a href=" ' . $ url . '&morder= ' . $ purifier -> purify ( urlencode ( $ morder)) . '#results"> ' .
381+ $ purifier -> purify ( svn_utils_field_get_label ($ attr) ) . '</a><img src=" ' . util_get_dir_image_theme () .
363382 ((substr ($ crit , -1 ) == '< ' ) ? 'dn ' : 'up ' ) .
364383 '_arrow.png" border="0"> ' ;
365384 }
@@ -783,7 +802,10 @@ function svn_utils_is_there_specific_permission($project_svnroot)
783802 return ! $ specifics || $ specifics != '' ;
784803}
785804
786- function svn_get_revisions (Project $ project , $ offset , $ chunksz , $ _rev_id = '' , $ _commiter = '' , $ _srch = '' , $ order_by = '' , $ pv = 0 , $ foundRows = true )
805+ /**
806+ * @psalm-param array<array{order:"ASC"|"DESC", column: "revision"|"commit_id"|"description"|"date"|"whoid"}> $order_by
807+ */
808+ function svn_get_revisions (Project $ project , $ offset , $ chunksz , $ _rev_id = '' , $ _commiter = '' , $ _srch = '' , array $ order_by = [], $ pv = 0 , $ foundRows = true )
787809{
788810 global $ _path ;
789811
@@ -852,17 +874,28 @@ function svn_get_revisions(Project $project, $offset, $chunksz, $_rev_id = '', $
852874
853875 $ where .= $ commiter_str . $ commit_str . $ srch_str . $ path_str ;
854876
877+ $ limit = '' ;
855878 if (! isset ($ pv ) || ! $ pv ) {
856879 $ limit = " LIMIT " . db_ei ($ offset ) . ", " . db_ei ($ chunksz );
857880 }
858881
859- // SQLi Warning: no real possibility to escape $order_by here.
860- // We rely on a proper filtering of user input by calling methods.
861- if (! isset ($ order_by ) || $ order_by == '' ) {
862- $ order_by = " ORDER BY revision DESC " ;
863- }
864-
865- $ sql = $ select . $ from . $ where . $ group_by . $ order_by . $ limit ;
882+ if (empty ($ order_by )) {
883+ $ order_by_sql = " ORDER BY revision DESC " ;
884+ } else {
885+ $ order_by_sql = ' ORDER BY ' ;
886+ $ order_by_sql .= implode (
887+ ', ' ,
888+ array_map (
889+ static function (array $ order_by_row ) {
890+ return $ order_by_row ['column ' ] . ' ' . $ order_by_row ['order ' ];
891+ },
892+ $ order_by
893+ )
894+ );
895+ $ order_by_sql .= ' ' ;
896+ }
897+
898+ $ sql = $ select . $ from . $ where . $ group_by . $ order_by_sql . $ limit ;
866899 //echo $sql."<br>\n";
867900 $ result = db_query ($ sql );
868901
@@ -871,7 +904,7 @@ function svn_get_revisions(Project $project, $offset, $chunksz, $_rev_id = '', $
871904 if ($ foundRows ) {
872905 $ sql1 = 'SELECT FOUND_ROWS() as nb ' ;
873906 $ result1 = db_query ($ sql1 );
874- if ($ result1 && ! db_error ($ result1 )) {
907+ if ($ result1 && ! db_error ()) {
875908 $ row1 = db_fetch_array ($ result1 );
876909 $ totalrows = $ row1 ['nb ' ];
877910 }
0 commit comments