1<?php 2 3use App\Repository\PackageRepository; 4 5$errors = []; 6$warnings = []; 7$order_options = [ 8 '' => 'relevance', 9 'id' => 'ID', 10 'ts1' => 'date', 11 'ts2' => 'last modified', 12 'package_name' => 'package', 13 'bug_type' => 'bug_type', 14 'status' => 'status', 15 'php_version' => 'php_version', 16 'php_os' => 'os', 17 'sdesc' => 'summary', 18 'assign' => 'assignment', 19 'avg_score' => 'avg. vote score', 20 'votes_count' => 'number of votes', 21 'RAND()' => 'random', 22]; 23 24// Fetch pseudo packages 25$packageRepository = $container->get(PackageRepository::class); 26$pseudo_pkgs = $packageRepository->findAll(); 27 28// Setup input variables.. 29$boolean_search = isset($_GET['boolean']) ? (int) $_GET['boolean'] : 0; 30$status = !empty($_GET['status']) ? (string)$_GET['status'] : 'Open'; 31$search_for = !empty($_GET['search_for']) ? trim((string)$_GET['search_for']) : ''; 32$bug_type = (!empty($_GET['bug_type']) && $_GET['bug_type'] != 'All') ? (string)$_GET['bug_type'] : ''; 33$bug_age = (int) (isset($_GET['bug_age']) ? $_GET['bug_age'] : 0); 34$bug_updated = (int) (isset($_GET['bug_updated']) ? $_GET['bug_updated'] : 0); 35$php_os = (!empty($_GET['php_os']) && is_string($_GET['php_os'])) ? $_GET['php_os'] : ''; 36$php_os_not = !empty($_GET['php_os_not']) ? 'not' : ''; 37$phpver = (!empty($_GET['phpver']) && is_string($_GET['phpver'])) ? $_GET['phpver'] : ''; 38$cve_id = (!empty($_GET['cve_id']) && is_string($_GET['cve_id'])) ? $_GET['cve_id'] : ''; 39$cve_id_not = !empty($_GET['cve_id_not']) ? 'not' : ''; 40$patch = (!empty($_GET['patch']) && is_string($_GET['patch'])) ? $_GET['patch'] : ''; 41$pull = (!empty($_GET['pull']) && is_string($_GET['pull'])) ? $_GET['pull'] : ''; 42$private = (!empty($_GET['private']) && is_string($_GET['private'])) ? $_GET['private'] : ''; 43$begin = (int) ((!empty($_GET['begin']) && $_GET['begin'] > 0) ? $_GET['begin'] : 0); 44$limit = (defined('MAX_BUGS_RETURN')) ? MAX_BUGS_RETURN : 30; 45$project = (!empty($_GET['project']) && $_GET['project'] != 'All') ? $_GET['project'] : ''; 46if (!empty($_GET['limit'])) { 47 $limit = ($_GET['limit'] == 'All') ? 'All' : (($_GET['limit'] > 0) ? (int) $_GET['limit'] : $limit); 48} 49$direction = (!empty($_GET['direction']) && $_GET['direction'] != 'DESC') ? 'ASC' : 'DESC'; 50$order_by = (!empty($_GET['order_by']) && array_key_exists($_GET['order_by'], $order_options)) ? $_GET['order_by'] : ''; 51$reorder_by = (!empty($_GET['reorder_by']) && array_key_exists($_GET['reorder_by'], $order_options)) ? $_GET['reorder_by'] : ''; 52$assign = (!empty($_GET['assign']) && is_string($_GET['assign'])) ? $_GET['assign'] : ''; 53$author_email = !empty($_GET['author_email']) ? spam_protect($_GET['author_email'], 'reverse') : ''; 54$package_name = (isset($_GET['package_name']) && is_array($_GET['package_name'])) ? $_GET['package_name'] : []; 55$package_nname = (isset($_GET['package_nname']) && is_array($_GET['package_nname'])) ? $_GET['package_nname'] : []; 56$commented_by = !empty($_GET['commented_by']) ? spam_protect($_GET['commented_by'], 'reverse') : ''; 57 58if (isset($_GET['cmd']) && $_GET['cmd'] == 'display') 59{ 60 $query = ' 61 SELECT SQL_CALC_FOUND_ROWS 62 bugdb.*, 63 TO_DAYS(NOW())-TO_DAYS(bugdb.ts2) AS unchanged, 64 UNIX_TIMESTAMP(ts1) AS submitted, 65 UNIX_TIMESTAMP(ts2) AS modified 66 FROM bugdb 67 '; 68 69 if (in_array($order_by, ['votes_count', 'avg_score'])) { 70 $query .= 'LEFT JOIN bugdb_votes v ON bugdb.id = v.bug'; 71 } 72 73 if ($commented_by != '') { 74 $query .= ' LEFT JOIN bugdb_comments c ON bugdb.id = c.bug'; 75 } 76 77 $where_clause = ' WHERE 1 = 1 '; 78 79 if (isset($user_flags) && ($user_flags & (BUGS_SECURITY_DEV | BUGS_TRUSTED_DEV))) { 80 if ($private != '') { 81 $where_clause .= ' AND bugdb.private = "Y" '; 82 } 83 } else { 84 /* Non trusted developer should see the Security related bug report just when it is public */ 85 $where_clause .= ' AND (bugdb.bug_type <> "Security" OR private = "N") '; 86 } 87 88 if (!empty($package_name)) { 89 $where_clause .= ' AND bugdb.package_name'; 90 if (count($package_name) > 1) { 91 $items = array_map([$dbh, 'quote'], $package_name); 92 $where_clause .= " IN (" . join(", ", $items) . ")"; 93 } else { 94 $where_clause .= ' = ' . $dbh->quote($package_name[0]); 95 } 96 } 97 98 if (!empty($package_nname)) { 99 $where_clause .= ' AND bugdb.package_name'; 100 if (count($package_nname) > 1) { 101 $items = array_map([$dbh, 'quote'], $package_nname); 102 $where_clause .= " NOT IN (" . join(", ", $items) . ")"; 103 } else { 104 $where_clause .= ' <> ' . $dbh->quote($package_nname[0]); 105 } 106 } 107 108 // Ensure status is valid and tweak search clause to treat assigned, analyzed, critical and verified bugs as open 109 switch ($status) { 110 case 'All': 111 break; 112 case 'Closed': 113 case 'Re-Opened': 114 case 'Duplicate': 115 case 'Critical': 116 case 'Assigned': 117 case 'Analyzed': 118 case 'Verified': 119 case 'Suspended': 120 case 'Wont fix': 121 case 'No Feedback': 122 case 'Feedback': 123 case 'Not a bug': 124 $where_clause .= " AND bugdb.status='$status'"; 125 break; 126 case 'Old Feedback': 127 $where_clause .= " AND bugdb.status='Feedback' 128 AND TO_DAYS(NOW())-TO_DAYS(bugdb.ts2) > 60"; 129 break; 130 case 'Fresh': 131 $where_clause .= " AND bugdb.status NOT IN ('Closed', 'Duplicate', 'Not a bug') 132 AND TO_DAYS(NOW())-TO_DAYS(bugdb.ts2) < 30"; 133 break; 134 case 'Stale': 135 $where_clause .= " AND bugdb.status NOT IN ('Closed', 'Duplicate', 'Not a bug') 136 AND TO_DAYS(NOW())-TO_DAYS(bugdb.ts2) > 30"; 137 break; 138 case 'Not Assigned': 139 $where_clause .= " AND bugdb.status NOT IN ('Closed', 'Duplicate', 'Not a bug', 'Assigned', 'Wont Fix', 'Suspended')"; 140 break; 141 case 'OpenFeedback': 142 $where_clause .= " AND bugdb.status IN ('Open', 'Re-Opened', 'Assigned','Analyzed', 'Critical', 'Verified', 'Feedback')"; 143 break; 144 default: 145 case 'Open': 146 $where_clause .= " AND bugdb.status IN ('Open', 'Re-Opened', 'Assigned', 'Analyzed', 'Critical', 'Verified')"; 147 } 148 149 if ($search_for != '') { 150 list($sql_search, $ignored) = format_search_string($search_for, $boolean_search); 151 $where_clause .= $sql_search; 152 if (count($ignored) > 0 ) { 153 $warnings[] = 'The following words were ignored: ' . implode(', ', array_unique($ignored)); 154 } 155 } 156 157 if ($bug_type != '') { 158 if ($bug_type == 'Bugs') { 159 $where_clause .= ' AND (bugdb.bug_type = "Bug" OR bugdb.bug_type="Documentation Problem")'; 160 } else { 161 $where_clause .= ' AND bugdb.bug_type = ' . $dbh->quote($bug_type); 162 } 163 } 164 165 if ($bug_age > 0) { 166 $where_clause .= " AND bugdb.ts1 >= DATE_SUB(NOW(), INTERVAL $bug_age DAY)"; 167 } 168 169 if ($bug_updated > 0) { 170 $where_clause .= " AND bugdb.ts2 >= DATE_SUB(NOW(), INTERVAL $bug_updated DAY)"; 171 } 172 173 if ($php_os != '') { 174 $where_clause .= " AND bugdb.php_os {$php_os_not} LIKE " . $dbh->quote('%'.$php_os.'%'); 175 } 176 177 if ($phpver != '') { 178 $where_clause .= " AND bugdb.php_version LIKE " . $dbh->quote($phpver.'%'); 179 } 180 181 if ($project != '') { 182 $where_clause .= " AND EXISTS (SELECT 1 FROM bugdb_pseudo_packages b WHERE b.name = bugdb.package_name AND b.project = ". $dbh->quote($project) ." LIMIT 1)"; 183 } 184 185 if ($cve_id != '') { 186 $where_clause .= " AND bugdb.cve_id {$cve_id_not} LIKE " . $dbh->quote($cve_id.'%'); 187 } 188 189 /* A search for patch&pull should be (patch or pull) */ 190 if ($patch != '' || $pull != '') { 191 $where_clause .= " AND (1=2"; 192 } 193 if ($patch != '') { 194 $where_clause .= " OR EXISTS (SELECT 1 FROM bugdb_patchtracker WHERE bugdb_id = bugdb.id LIMIT 1)"; 195 } 196 if ($pull != '') { 197 $where_clause .= " OR EXISTS (SELECT 1 FROM bugdb_pulls WHERE bugdb_id = bugdb.id LIMIT 1)"; 198 } 199 if ($patch != '' || $pull != '') { 200 $where_clause .= ")"; 201 } 202 if ($assign != '') { 203 $where_clause .= ' AND bugdb.assign = ' . $dbh->quote($assign); 204 } 205 206 if ($author_email != '') { 207 $where_clause .= ' AND bugdb.email = ' . $dbh->quote($author_email); 208 } 209 if ($commented_by != '') { 210 $where_clause .= ' AND c.email = ' . $dbh->quote($commented_by); 211 } 212 213 $where_clause .= ' AND (1=1'; 214 215 if ($pseudo = array_intersect(array_keys($pseudo_pkgs), $package_name)) { 216 $where_clause .= " OR bugdb.package_name"; 217 if (count($pseudo) > 1) { 218 $pseudo = array_map([$dbh, 'quote'], $pseudo); 219 $where_clause .= " IN (" . join(", ", $pseudo) . ")"; 220 } else { 221 $where_clause .= " = " . $dbh->quote(reset($pseudo)); 222 } 223 } else { 224 $items = array_map([$dbh, 'quote'], array_keys($pseudo_pkgs)); 225 $where_clause .= " OR bugdb.package_name IN (" . join(", ", $items) . ")"; 226 } 227 228 $query .= "$where_clause )"; 229 230 if ($reorder_by != '') { 231 if ($order_by == $reorder_by) { 232 $direction = $direction == 'ASC' ? 'DESC' : 'ASC'; 233 } else { 234 $direction = $reorder_by == 'ts2' ? 'DESC' : 'ASC'; 235 $order_by = $reorder_by; 236 } 237 } 238 239 $order_by_clauses = []; 240 if (in_array($order_by, ['votes_count', 'avg_score'])) { 241 $query .= ' GROUP BY bugdb.id'; 242 243 switch ($order_by) { 244 case 'avg_score': 245 $order_by_clauses = [ 246 "IFNULL(AVG(v.score), 0)+3 $direction", 247 "COUNT(v.bug) DESC" 248 ]; 249 break; 250 case 'votes_count': 251 $order_by_clauses = ["COUNT(v.bug) $direction"]; 252 break; 253 } 254 } elseif ($order_by != '') { 255 $order_by_clauses = ["$order_by $direction"]; 256 } 257 258 if ($status == 'Feedback') { 259 $order_by_clauses[] = "bugdb.ts2 $direction"; 260 } 261 262 if (count($order_by_clauses)) { 263 $query .= ' ORDER BY ' . implode(', ', $order_by_clauses); 264 } 265 266 if ($limit != 'All' && $limit > 0) { 267 $query .= " LIMIT $begin, $limit"; 268 } 269 270 if (stristr($query, ';')) { 271 $errors[] = 'BAD HACKER!! No database cracking for you today!'; 272 } else { 273 try { 274 $result = $dbh->prepare($query)->execute()->fetchAll(); 275 $rows = count($result); 276 $total_rows = $dbh->prepare('SELECT FOUND_ROWS()')->execute()->fetch(\PDO::FETCH_NUM)[0]; 277 } catch (Exception $e) { 278 $errors[] = 'Invalid query' /*. $e->getMessage() */; 279 } 280 if (defined('MAX_BUGS_RETURN') && $total_rows > $rows) { 281 $warnings[] = 'The search was too general, only ' . MAX_BUGS_RETURN . ' bugs will be returned'; 282 } 283 } 284} 285