This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /* zKillboard |
||
3 | * Copyright (C) 2012-2015 EVE-KILL Team and EVSCO. |
||
4 | * |
||
5 | * This program is free software: you can redistribute it and/or modify |
||
6 | * it under the terms of the GNU Affero General Public License as published by |
||
7 | * the Free Software Foundation, either version 3 of the License, or |
||
8 | * (at your option) any later version. |
||
9 | * |
||
10 | * This program is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | * GNU Affero General Public License for more details. |
||
14 | * |
||
15 | * You should have received a copy of the GNU Affero General Public License |
||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
17 | */ |
||
18 | class Util |
||
19 | { |
||
20 | public static function isMaintenanceMode() |
||
21 | { |
||
22 | return "true" == Db::queryField("select contents from zz_storage where locker = 'maintenance'", "contents", array(), 0); |
||
23 | } |
||
24 | |||
25 | public static function getMaintenanceReason() |
||
26 | { |
||
27 | return Storage::retrieve("MaintenanceReason", ""); |
||
28 | } |
||
29 | |||
30 | public static function getNotification() |
||
31 | { |
||
32 | return Storage::retrieve("notification", null); |
||
33 | } |
||
34 | |||
35 | public static function is904Error() |
||
36 | { |
||
37 | $stop904 = Db::queryField("select count(*) count from zz_storage where locker = 'ApiStop904' and contents > now()", "count", array(), 1); |
||
38 | return $stop904 > 0; |
||
39 | } |
||
40 | |||
41 | public static function getCrest($url) |
||
42 | { |
||
43 | StatsD::increment("crest_calls"); |
||
44 | \Perry\Setup::$fetcherOptions = ["connect_timeout" => 15, "timeout" => 30]; |
||
45 | return \Perry\Perry::fromUrl($url); |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * @param integer $keyID |
||
50 | * @param string $vCode |
||
51 | */ |
||
52 | public static function getPheal($keyID = null, $vCode = null) |
||
53 | { |
||
54 | global $phealCacheLocation, $apiServer, $baseAddr, $ipsAvailable; |
||
55 | |||
56 | if (static::is904Error()) |
||
57 | { |
||
58 | // Web requests shouldn't be hitting the API... |
||
59 | if (php_sapi_name() == 'cli') |
||
60 | exit(); |
||
61 | |||
62 | return null; |
||
63 | } |
||
64 | |||
65 | \Pheal\Core\Config::getInstance()->http_method = "curl"; |
||
0 ignored issues
–
show
|
|||
66 | \Pheal\Core\Config::getInstance()->http_user_agent = "API Fetcher for http://$baseAddr"; |
||
67 | if(!empty($ipsAvailable)) |
||
68 | { |
||
69 | $max = count($ipsAvailable)-1; |
||
70 | $ipID = mt_rand(0, $max); |
||
71 | \Pheal\Core\Config::getInstance()->http_interface_ip = $ipsAvailable[$ipID]; |
||
72 | } |
||
73 | \Pheal\Core\Config::getInstance()->http_post = false; |
||
74 | \Pheal\Core\Config::getInstance()->http_keepalive = true; // default 15 seconds |
||
75 | \Pheal\Core\Config::getInstance()->http_keepalive = 10; // KeepAliveTimeout in seconds |
||
76 | \Pheal\Core\Config::getInstance()->http_timeout = 30; |
||
77 | \Pheal\Core\Config::getInstance()->http_ssl_verifypeer = false; |
||
78 | |||
79 | if ($phealCacheLocation != null) |
||
80 | \Pheal\Core\Config::getInstance()->cache = new \Pheal\Cache\FileStorage($phealCacheLocation); // Implement own cache class that calls statsD |
||
81 | \Pheal\Core\Config::getInstance()->log = new PhealLogger(); |
||
82 | \Pheal\Core\Config::getInstance()->api_customkeys = true; |
||
83 | \Pheal\Core\Config::getInstance()->api_base = $apiServer; |
||
84 | |||
85 | if ($keyID != null && $vCode != null) |
||
86 | $pheal = new \Pheal\Pheal($keyID, $vCode); |
||
87 | else |
||
88 | $pheal = new \Pheal\Pheal(); |
||
89 | |||
90 | // Stats gathering, sadly phealng has no way of telling us if we're hitting the cache or not. |
||
91 | StatsD::increment("ccp_api"); |
||
92 | |||
93 | // Return the API data to whomever requested it. |
||
94 | return $pheal; |
||
95 | } |
||
96 | |||
97 | public static function pluralize($string) |
||
98 | { |
||
99 | if (!self::endsWith($string, "s")) return $string . "s"; |
||
100 | else return $string . "es"; |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * @param string $haystack |
||
105 | * @param string $needle |
||
106 | */ |
||
107 | public static function startsWith($haystack, $needle) |
||
108 | { |
||
109 | $length = strlen($needle); |
||
110 | return (substr($haystack, 0, $length) === $needle); |
||
111 | } |
||
112 | |||
113 | public static function endsWith($haystack, $needle) |
||
114 | { |
||
115 | return substr($haystack, -strlen($needle)) === $needle; |
||
116 | } |
||
117 | |||
118 | public static function getKillHash($killID = null, $kill = null) |
||
119 | { |
||
120 | if ($killID != null) { |
||
121 | $json = Killmail::get($killID); |
||
122 | if ($json === null) throw new Exception("Cannot find kill $killID"); |
||
123 | $kill = json_decode($json); |
||
124 | if ($kill === null) throw new Exception("Cannot json_decode $killID"); |
||
125 | } |
||
126 | if ($kill === null) throw new Exception("Can't hash an empty kill"); |
||
127 | |||
128 | $hashStr = ""; |
||
129 | $hashStr .= ":$kill->killTime:$kill->solarSystemID:$kill->moonID:"; |
||
130 | $victim = $kill->victim; |
||
131 | $hashStr .= ":$victim->characterID:$victim->shipTypeID:$victim->damageTaken:"; |
||
132 | |||
133 | return hash("sha256", $hashStr); |
||
134 | } |
||
135 | |||
136 | public static function calcX($slot, $size) |
||
137 | { |
||
138 | $angle = $slot * (360 / 32) - 4; |
||
139 | $rad = deg2rad($angle); |
||
140 | $radius = $size / 2; |
||
141 | return (int)(($radius * cos($rad))); |
||
142 | } |
||
143 | |||
144 | public static function calcY($slot, $size) |
||
145 | { |
||
146 | $angle = $slot * (360 / 32) - 4; |
||
147 | $rad = deg2rad($angle); |
||
148 | $radius = $size / 2; |
||
149 | return (int)(($radius * sin($rad))); |
||
150 | } |
||
151 | |||
152 | private static $formatIskIndexes = array("", "k", "m", "b", "t", "tt", "ttt"); |
||
153 | |||
154 | public static function formatIsk($value) |
||
155 | { |
||
156 | $numDecimals = (((int)$value) == $value) && $value < 10000 ? 0 : 2; |
||
157 | if ($value == 0) return number_format(0, $numDecimals); |
||
158 | if ($value < 10000) return number_format($value, $numDecimals); |
||
159 | $iskIndex = 0; |
||
160 | while ($value > 999.99) { |
||
161 | $value /= 1000; |
||
162 | $iskIndex++; |
||
163 | } |
||
164 | return number_format($value, $numDecimals) . self::$formatIskIndexes[$iskIndex]; |
||
165 | } |
||
166 | |||
167 | public static function convertUriToParameters($additionalParameters = array(), $addExtraParameters = true) |
||
168 | { |
||
169 | $parameters = array(); |
||
170 | @$uri = $_SERVER["REQUEST_URI"]; |
||
171 | $split = explode("/", $uri); |
||
172 | $currentIndex = 0; |
||
173 | foreach ($split as $key) |
||
174 | { |
||
175 | $value = $currentIndex + 1 < count($split) ? $split[$currentIndex + 1] : null; |
||
176 | switch ($key) { |
||
177 | case "groupID": |
||
178 | // do nothing |
||
179 | break; |
||
180 | case "kills": |
||
181 | case "losses": |
||
182 | case "w-space": |
||
183 | case "lowsec": |
||
184 | case "nullsec": |
||
185 | case "highsec": |
||
186 | case "solo": |
||
187 | $parameters[$key] = true; |
||
188 | break; |
||
189 | case "characterID": |
||
190 | case "corporationID": |
||
191 | case "allianceID": |
||
192 | case "factionID": |
||
193 | case "shipID": |
||
194 | case "shipTypeID": |
||
195 | case "solarSystemID": |
||
196 | case "systemID": |
||
197 | case "regionID": |
||
198 | if ($value != null) { |
||
199 | if (strpos($key, "ID") === false) $key = $key . "ID"; |
||
200 | if ($key == "systemID") $key = "solarSystemID"; |
||
201 | else if ($key == "shipID") $key = "shipTypeID"; |
||
202 | $exploded = explode(",", $value); |
||
203 | foreach($exploded as $aValue) |
||
204 | { |
||
205 | if ($aValue != (int) $aValue || ((int) $aValue) == 0) throw new Exception("Invalid ID passed: $aValue"); |
||
206 | } |
||
207 | if (sizeof($exploded) > 10) throw new Exception("Too many IDs! Max: 10"); |
||
208 | $parameters[$key] = $exploded; |
||
209 | } |
||
210 | break; |
||
211 | case "page": |
||
212 | $value = (int)$value; |
||
213 | if ($value < 1) $value = 1; |
||
214 | $parameters[$key] = $value; |
||
215 | break; |
||
216 | case "orderDirection": |
||
217 | if (!($value == "asc" || $value == "desc")) throw new Exception("Invalid orderDirection! Allowed: asc, desc"); |
||
218 | $parameters[$key] = "desc"; // only desc |
||
219 | //$parameters[$key] = $value; |
||
220 | break; |
||
221 | case "pastSeconds": |
||
222 | $value = (int) $value; |
||
223 | if (($value / 86400) > 7) throw new Exception("pastSeconds is limited to a max of 7 days"); |
||
224 | $parameters[$key] = $value; |
||
225 | break; |
||
226 | case "startTime": |
||
227 | case "endTime": |
||
228 | $time = strtotime($value); |
||
229 | if($time < 0) throw new Exception("$value is not a valid time format"); |
||
230 | $parameters[$key] = $value; |
||
231 | break; |
||
232 | case "limit": |
||
233 | $value = (int) $value; |
||
234 | if ($value <= 1000) $parameters["limit"] = $value; |
||
235 | elseif($value > 1000) $parameters["limit"] = 1000; |
||
236 | elseif($value <= 0) $parameters["limit"] = 1; |
||
237 | break; |
||
238 | case "beforeKillID": |
||
239 | case "afterKillID": |
||
240 | case "killID": |
||
241 | if (!is_numeric($value)) throw new Exception("$value is not a valid entry for $key"); |
||
242 | $parameters[$key] = (int) $value; |
||
243 | break; |
||
244 | case "iskValue": |
||
245 | if (!is_numeric($value)) throw new Exception("$value is not a valid entry for $key"); |
||
246 | $parameters[$key] = (int) $value; |
||
247 | break; |
||
248 | case "xml": |
||
249 | $parameters[$key] = true; |
||
250 | break; |
||
251 | case "pretty": |
||
252 | $parameters[$key] = true; |
||
253 | break; |
||
254 | case "no-attackers": |
||
255 | $parameters[$key] = true; |
||
256 | break; |
||
257 | case "no-items": |
||
258 | $parameters[$key] = true; |
||
259 | break; |
||
260 | case "finalblow-only": |
||
261 | $parameters[$key] = true; |
||
262 | break; |
||
263 | case "api": |
||
264 | $parameters[$key] = true; |
||
265 | break; |
||
266 | default: |
||
267 | if($addExtraParameters == true) |
||
268 | { |
||
269 | if (is_numeric($value) && $value < 0) continue; //throw new Exception("$value is not a valid entry for $key"); |
||
270 | if ($key != "" && $value != "") $parameters[$key] = $value; |
||
271 | } |
||
272 | |||
273 | // Add more parameters to the $parameters array |
||
274 | if(!empty($additionalParameters)) |
||
275 | { |
||
276 | foreach($additionalParameters as $extra) |
||
277 | if($extra == $key) |
||
278 | $parameters[$key] = $value; |
||
279 | } |
||
280 | break; |
||
281 | } |
||
282 | $currentIndex++; |
||
283 | } |
||
284 | |||
285 | if (isset($parameters["page"]) && $parameters["page"] > 10 && isset($parameters["api"])) { |
||
286 | // Verify that the request is for a character, corporation, or alliance |
||
287 | // This will prevent scrape attempts against regions, ships, systems, etc. which |
||
288 | // are very hard against the database |
||
289 | $legitEntities = array("characterID", "corporationID", "allianceID"); |
||
290 | $legit = false; |
||
291 | foreach ($legitEntities as $entity) { |
||
292 | $legit |= in_array($entity, array_keys($parameters)); |
||
293 | } |
||
294 | // The API doesn't handle Exceptions that well, so we have to output json/xml for them.. |
||
295 | if (!$legit) |
||
296 | { |
||
297 | $date = date("Y-m-d H:i:s"); |
||
298 | $cachedUntil = date("Y-m-d H:i:s", time() + 3600); |
||
299 | if(stristr($_SERVER["REQUEST_URI"], "xml")) |
||
300 | { |
||
301 | $data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?" . ">"; // separating the ? and > allows vi to still color format code nicely |
||
302 | $data .= "<eveapi version=\"2\" zkbapi=\"1\">"; |
||
303 | $data .= "<currentTime>$date</currentTime>"; |
||
304 | $data .= "<result>"; |
||
305 | $data .= "<error>A maximum of 10 pages is allowed for the modifier type you are using.</error>"; |
||
306 | $data .= "</result>"; |
||
307 | $data .= "<cachedUntil>$cachedUntil</cachedUntil>"; |
||
308 | $data .= "</eveapi>"; |
||
309 | header("Content-type: text/xml; charset=utf-8"); |
||
310 | } |
||
311 | else |
||
312 | { |
||
313 | header("Content-type: application/json; charset=utf-8"); |
||
314 | $data = json_encode(array("Error" => "A maximum of 10 pages is allowed for the modifier type you are using.", "cachedUntil" => $cachedUntil)); |
||
315 | } |
||
316 | header("Retry-After: " . $cachedUntil . " GMT"); |
||
317 | header("HTTP/1.1 409 Conflict"); |
||
318 | header("Etag: ".(md5(serialize($data)))); |
||
319 | echo $data; |
||
320 | die(); |
||
321 | } |
||
322 | } |
||
323 | return $parameters; |
||
324 | } |
||
325 | |||
326 | public static function shortString($string, $maxLength = 8) |
||
327 | { |
||
328 | if (strlen($string) <= $maxLength) return $string; |
||
329 | return substr($string, 0, $maxLength - 3) . "..."; |
||
330 | } |
||
331 | |||
332 | public static function truncate($str, $length = 200, $trailing = "...") |
||
333 | { |
||
334 | $length -= mb_strlen($trailing); |
||
335 | if (mb_strlen($str) > $length) { |
||
336 | // string exceeded length, truncate and add trailing dots |
||
337 | return mb_substr($str, 0, $length) . $trailing; |
||
338 | } |
||
339 | else |
||
340 | { |
||
341 | // string was already short enough, return the string |
||
342 | $res = $str; |
||
343 | } |
||
344 | return $res; |
||
345 | } |
||
346 | |||
347 | public static function pageTimer() |
||
348 | { |
||
349 | global $timer; |
||
350 | return $timer->stop(); |
||
351 | } |
||
352 | |||
353 | public static function isActive($pageType, $currentPage, $retValue = "active") |
||
354 | { |
||
355 | return strtolower($pageType) == strtolower($currentPage) ? $retValue : ""; |
||
356 | } |
||
357 | |||
358 | private static $months = array("", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"); |
||
359 | |||
360 | public static function getMonth($month) |
||
361 | { |
||
362 | return self::$months[$month]; |
||
363 | } |
||
364 | |||
365 | private static $longMonths = array("", "January", "February", "March", "April", "May", "June", "July", "August", |
||
366 | "September", "October", "November", "December"); |
||
367 | |||
368 | public static function getLongMonth($month) |
||
369 | { |
||
370 | return self::$longMonths[$month]; |
||
371 | } |
||
372 | |||
373 | public static function deleteKill($killID) |
||
374 | { |
||
375 | if($killID < 0) |
||
376 | { |
||
377 | // Verify the kill exists |
||
378 | $count = Db::execute("select count(*) count from zz_killmails where killID = :killID", array(":killID" => $killID)); |
||
379 | if ($count == 0) return false; |
||
380 | // Remove it from the stats |
||
381 | Stats::calcStats($killID, false); |
||
382 | // Remove it from the kill tables |
||
383 | Db::execute("delete from zz_participants where killID = :killID", array(":killID" => $killID)); |
||
384 | // Mark the kill as deleted |
||
385 | Db::execute("update zz_killmails set processed = 2 where killID = :killID", array(":killID" => $killID)); |
||
386 | return true; |
||
387 | } |
||
388 | return false; |
||
389 | } |
||
390 | |||
391 | public static function themesAvailable() |
||
392 | { |
||
393 | $dir = "themes/"; |
||
394 | $avail = scandir($dir); |
||
395 | foreach($avail as $key => $val) |
||
396 | if($val == "." || $val == "..") |
||
397 | unset($avail[$key]); |
||
398 | return $avail; |
||
399 | } |
||
400 | |||
401 | /** |
||
402 | * @param string $haystack |
||
403 | */ |
||
404 | public static function strposa($haystack, $needles=array(), $offset=0) |
||
405 | { |
||
406 | $chr = array(); |
||
407 | foreach($needles as $needle) { |
||
408 | $res = strpos($haystack, $needle, $offset); |
||
409 | if ($res !== false) $chr[$needle] = $res; |
||
410 | } |
||
411 | if(empty($chr)) return false; |
||
412 | return min($chr); |
||
413 | } |
||
414 | |||
415 | /** |
||
416 | * @param string $url |
||
417 | * @return string|null $result |
||
418 | */ |
||
419 | public static function getData($url, $cacheTime = 3600) |
||
420 | { |
||
421 | global $ipsAvailable, $baseAddr; |
||
422 | |||
423 | $md5 = md5($url); |
||
424 | $result = $cacheTime > 0 ? Cache::get($md5) : null; |
||
425 | |||
426 | if(!$result) |
||
427 | { |
||
428 | $curl = curl_init(); |
||
429 | curl_setopt_array($curl, array( |
||
430 | CURLOPT_USERAGENT => "zKillboard dataGetter for site: {$baseAddr}", |
||
431 | CURLOPT_TIMEOUT => 30, |
||
432 | CURLOPT_POST => false, |
||
433 | CURLOPT_FORBID_REUSE => false, |
||
434 | CURLOPT_ENCODING => "", |
||
435 | CURLOPT_URL => $url, |
||
436 | CURLOPT_HTTPHEADER => array("Connection: keep-alive", "Keep-Alive: timeout=10, max=1000"), |
||
437 | CURLOPT_RETURNTRANSFER => true, |
||
438 | CURLOPT_FAILONERROR => true |
||
439 | ) |
||
440 | ); |
||
441 | |||
442 | if(count($ipsAvailable) > 1) |
||
443 | { |
||
444 | $ip = $ipsAvailable[time() % count($ipsAvailable)]; |
||
445 | curl_setopt($curl, CURLOPT_INTERFACE, $ip); |
||
446 | } |
||
447 | $result = curl_exec($curl); |
||
448 | if ($cacheTime > 0) Cache::set($md5, $result, $cacheTime); |
||
449 | } |
||
450 | |||
451 | return $result; |
||
452 | } |
||
453 | |||
454 | /** |
||
455 | * @param string $url |
||
456 | * @param array |
||
457 | * @param array |
||
458 | * @return array $result |
||
459 | */ |
||
460 | public static function postData($url, $postData = array(), $headers = array()) |
||
461 | { |
||
462 | global $ipsAvailable, $baseAddr; |
||
463 | $userAgent = "zKillboard dataGetter for site: {$baseAddr}"; |
||
464 | if(!isset($headers)) |
||
465 | $headers = array("Connection: keep-alive", "Keep-Alive: timeout=10, max=1000"); |
||
466 | |||
467 | $curl = curl_init(); |
||
468 | $postLine = ""; |
||
469 | |||
470 | if(!empty($postData)) |
||
471 | foreach($postData as $key => $value) |
||
472 | $postLine .= $key . "=" . $value . "&"; |
||
473 | |||
474 | rtrim($postLine, "&"); |
||
475 | |||
476 | curl_setopt($curl, CURLOPT_URL, $url); |
||
477 | curl_setopt($curl, CURLOPT_USERAGENT, $userAgent); |
||
478 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); |
||
479 | if(!empty($postData)) |
||
480 | { |
||
481 | curl_setopt($curl, CURLOPT_POST, count($postData)); |
||
482 | curl_setopt($curl, CURLOPT_POSTFIELDS, $postLine); |
||
483 | } |
||
484 | |||
485 | if(count($ipsAvailable) > 0) |
||
486 | { |
||
487 | $ip = $ipsAvailable[time() % count($ipsAvailable)]; |
||
488 | curl_setopt($curl, CURLOPT_INTERFACE, $ip); |
||
489 | } |
||
490 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |
||
491 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); |
||
492 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); |
||
493 | |||
494 | $result = curl_exec($curl); |
||
495 | |||
496 | curl_close($curl); |
||
497 | return $result; |
||
498 | } |
||
499 | |||
500 | /** |
||
501 | * Gets post data, and returns it |
||
502 | * @param string $var The variable you can to return |
||
503 | * @return string|null |
||
504 | */ |
||
505 | public static function getPost($var) |
||
506 | { |
||
507 | return isset($_POST[$var]) ? $_POST[$var] : null; |
||
508 | } |
||
509 | |||
510 | public static function informationPages() |
||
511 | { |
||
512 | global $baseDir, $theme; |
||
513 | $tDir = $baseDir . "themes/" . $theme . "/information/"; |
||
514 | $data = null; |
||
515 | $pages = array(); |
||
516 | |||
517 | if(is_dir($tDir)) |
||
518 | $data = scandir($tDir); |
||
519 | |||
520 | if($data) |
||
521 | { |
||
522 | foreach($data as $key => $file) |
||
523 | { |
||
524 | if($file == "." || $file == "..") |
||
525 | continue; |
||
526 | |||
527 | if(is_dir($tDir . $file)) |
||
528 | { |
||
529 | $subData = scandir($tDir . $file); |
||
530 | foreach($subData as $key => $subDir) |
||
531 | { |
||
532 | if($subDir == "." || $subDir == "..") |
||
533 | continue; |
||
534 | |||
535 | $pages[$file][] = array("name" => strtolower(str_replace(".md", "", $subDir)), "path" => "$tDir$file/$subDir"); |
||
536 | } |
||
537 | } |
||
538 | else |
||
539 | $pages[strtolower(str_replace(".md", "", $file))][] = array("name" => strtolower(str_replace(".md", "", $file)), "path" => "$tDir$file"); |
||
540 | } |
||
541 | } |
||
542 | return $pages; |
||
543 | } |
||
544 | } |
||
545 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.