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 defined('SYSPATH') or die('No direct access allowed.'); |
||
2 | /** |
||
3 | * URL helper class. |
||
4 | * |
||
5 | * $Id: url.php 4029 2009-03-03 12:39:32Z Shadowhand $ |
||
6 | * |
||
7 | * @package Core |
||
8 | * @author Kohana Team |
||
9 | * @copyright (c) 2007-2008 Kohana Team |
||
10 | * @license http://kohanaphp.com/license.html |
||
11 | */ |
||
12 | class url_Core |
||
13 | { |
||
14 | |||
15 | /** |
||
16 | * Fetches the current URI. |
||
17 | * |
||
18 | * @param boolean include the query string |
||
19 | * @return string |
||
20 | */ |
||
21 | public static function current($qs = false) |
||
0 ignored issues
–
show
|
|||
22 | { |
||
23 | return ($qs === true) ? Router::$complete_uri : Router::$current_uri; |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * Base URL, with or without the index page. |
||
28 | * |
||
29 | * If protocol (and core.site_protocol) and core.site_domain are both empty, |
||
30 | * then |
||
31 | * |
||
32 | * @param boolean include the index page |
||
33 | * @param boolean non-default protocol |
||
34 | * @return string |
||
35 | */ |
||
36 | public static function base($index = false, $protocol = false) |
||
0 ignored issues
–
show
base uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
37 | { |
||
38 | if ($protocol == false) { |
||
0 ignored issues
–
show
|
|||
39 | // Use the default configured protocol |
||
40 | $protocol = Kohana::config('core.site_protocol'); |
||
41 | } |
||
42 | |||
43 | // Load the site domain |
||
44 | $site_domain = (string) Kohana::config('core.site_domain', true); |
||
45 | |||
46 | if ($protocol == false) { |
||
47 | if ($site_domain === '' or $site_domain[0] === '/') { |
||
48 | // Use the configured site domain |
||
49 | $base_url = $site_domain; |
||
50 | } else { |
||
51 | // Guess the protocol to provide full http://domain/path URL |
||
52 | $base_url = ((empty($_SERVER['HTTPS']) or $_SERVER['HTTPS'] === 'off') ? 'http' : 'https').'://'.$site_domain; |
||
53 | } |
||
54 | } else { |
||
55 | if ($site_domain === '' or $site_domain[0] === '/') { |
||
56 | // Guess the server name if the domain starts with slash |
||
57 | $base_url = $protocol.'://'.$_SERVER['HTTP_HOST'].$site_domain; |
||
58 | } else { |
||
59 | // Use the configured site domain |
||
60 | $base_url = $protocol.'://'.$site_domain; |
||
61 | } |
||
62 | } |
||
63 | |||
64 | if ($index === true and $index = Kohana::config('core.index_page')) { |
||
65 | // Append the index page |
||
66 | $base_url = $base_url.$index; |
||
67 | } |
||
68 | |||
69 | // Force a slash on the end of the URL |
||
70 | return rtrim($base_url, '/').'/'; |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * Fetches an absolute site URL based on a URI segment. |
||
75 | * |
||
76 | * @param string site URI to convert |
||
77 | * @param string non-default protocol |
||
78 | * @return string |
||
79 | */ |
||
80 | public static function site($uri = '', $protocol = false) |
||
81 | { |
||
82 | if ($path = trim(parse_url($uri, PHP_URL_PATH), '/')) { |
||
83 | // Add path suffix |
||
84 | $path .= Kohana::config('core.url_suffix'); |
||
85 | } |
||
86 | |||
87 | if ($query = parse_url($uri, PHP_URL_QUERY)) { |
||
88 | // ?query=string |
||
89 | $query = '?'.$query; |
||
90 | } |
||
91 | |||
92 | if ($fragment = parse_url($uri, PHP_URL_FRAGMENT)) { |
||
93 | // #fragment |
||
94 | $fragment = '#'.$fragment; |
||
95 | } |
||
96 | |||
97 | // Concat the URL |
||
98 | return url::base(true, $protocol).$path.$query.$fragment; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * Return the URL to a file. Absolute filenames and relative filenames |
||
103 | * are allowed. |
||
104 | * |
||
105 | * @param string filename |
||
106 | * @param boolean include the index page |
||
107 | * @return string |
||
108 | */ |
||
109 | public static function file($file, $index = false) |
||
110 | { |
||
111 | if (strpos($file, '://') === false) { |
||
112 | // Add the base URL to the filename |
||
113 | $file = url::base($index).$file; |
||
114 | } |
||
115 | |||
116 | return $file; |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Merges an array of arguments with the current URI and query string to |
||
121 | * overload, instead of replace, the current query string. |
||
122 | * |
||
123 | * @param array associative array of arguments |
||
124 | * @return string |
||
125 | */ |
||
126 | public static function merge(array $arguments) |
||
0 ignored issues
–
show
merge uses the super-global variable $_GET which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
127 | { |
||
128 | if ($_GET === $arguments) { |
||
129 | $query = Router::$query_string; |
||
130 | } elseif ($query = http_build_query(array_merge($_GET, $arguments))) { |
||
131 | $query = '?'.$query; |
||
132 | } |
||
133 | |||
134 | // Return the current URI with the arguments merged into the query string |
||
135 | return Router::$current_uri.$query; |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Convert a phrase to a URL-safe title. |
||
140 | * |
||
141 | * @param string phrase to convert |
||
142 | * @param string word separator (- or _) |
||
143 | * @return string |
||
144 | */ |
||
145 | public static function title($title, $separator = '-') |
||
146 | { |
||
147 | $separator = ($separator === '-') ? '-' : '_'; |
||
148 | |||
149 | // Replace accented characters by their unaccented equivalents |
||
150 | $title = utf8::transliterate_to_ascii($title); |
||
151 | |||
152 | // Remove all characters that are not the separator, a-z, 0-9, or whitespace |
||
153 | $title = preg_replace('/[^'.$separator.'a-z0-9\s]+/', '', strtolower($title)); |
||
154 | |||
155 | // Replace all separator characters and whitespace by a single separator |
||
156 | $title = preg_replace('/['.$separator.'\s]+/', $separator, $title); |
||
157 | |||
158 | // Trim separators from the beginning and end |
||
159 | return trim($title, $separator); |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Sends a page redirect header and runs the system.redirect Event. |
||
164 | * |
||
165 | * @param mixed string site URI or URL to redirect to, or array of strings if method is 300 |
||
166 | * @param string HTTP method of redirect |
||
167 | * @return false|null |
||
168 | */ |
||
169 | public static function redirect($uri = '', $method = '302') |
||
170 | { |
||
171 | if (Event::has_run('system.send_headers')) { |
||
172 | return false; |
||
173 | } |
||
174 | |||
175 | $codes = array( |
||
176 | 'refresh' => 'Refresh', |
||
177 | '300' => 'Multiple Choices', |
||
178 | '301' => 'Moved Permanently', |
||
179 | '302' => 'Found', |
||
180 | '303' => 'See Other', |
||
181 | '304' => 'Not Modified', |
||
182 | '305' => 'Use Proxy', |
||
183 | '307' => 'Temporary Redirect' |
||
184 | ); |
||
185 | |||
186 | // Validate the method and default to 302 |
||
187 | $method = isset($codes[$method]) ? (string) $method : '302'; |
||
188 | |||
189 | if ($method === '300') { |
||
190 | $uri = (array) $uri; |
||
191 | |||
192 | $output = '<ul>'; |
||
193 | foreach ($uri as $link) { |
||
194 | $output .= '<li>'.html::anchor($link).'</li>'; |
||
195 | } |
||
196 | $output .= '</ul>'; |
||
197 | |||
198 | // The first URI will be used for the Location header |
||
199 | $uri = $uri[0]; |
||
200 | } else { |
||
201 | $output = '<p>'.html::anchor($uri).'</p>'; |
||
202 | } |
||
203 | |||
204 | // Run the redirect event |
||
205 | Event::run('system.redirect', $uri); |
||
206 | |||
207 | if (strpos($uri, '://') === false) { |
||
208 | // HTTP headers expect absolute URLs |
||
209 | $uri = url::site($uri, request::protocol()); |
||
210 | } |
||
211 | |||
212 | if ($method === 'refresh') { |
||
213 | header('Refresh: 0; url='.$uri); |
||
214 | } else { |
||
215 | header('HTTP/1.1 '.$method.' '.$codes[$method]); |
||
216 | header('Location: '.$uri); |
||
217 | } |
||
218 | |||
219 | // We are about to exit, so run the send_headers event |
||
220 | Event::run('system.send_headers'); |
||
221 | |||
222 | exit('<h1>'.$method.' - '.$codes[$method].'</h1>'.$output); |
||
0 ignored issues
–
show
The method
redirect() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
223 | } |
||
224 | } // End url |
||
225 |
Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.