public function xss_in_merged_url_test() { Router::$current_uri = "foo/<xss>/bar"; Router::$complete_uri = "foo/<xss>/bar?foo=bar"; $_GET = array("foo" => "bar"); $this->assert_same("foo/<xss>/bar?foo=bar", url::merge(array())); $this->assert_same("foo/<xss>/bar?foo=bar&a=b", url::merge(array("a" => "b"))); }
protected function setUp() { // Save config $this->kohana_config['core.url_suffix'] = Kohana_Config::instance()->get('core.url_suffix'); // Save Server API $this->kohana_server_api = Kohana::$server_api; // Save Router members $this->router_vars = array('complete_uri' => Router::$complete_uri, 'controller' => Router::$controller, 'current_uri' => Router::$current_uri, 'query_string' => Router::$query_string, 'rsegments' => Router::$rsegments, 'routed_uri' => Router::$routed_uri, 'segments' => Router::$segments, 'url_suffix' => Router::$url_suffix); // Reset Router members Router::$complete_uri = ''; Router::$controller = NULL; Router::$current_uri = ''; Router::$query_string = ''; Router::$rsegments = NULL; Router::$routed_uri = ''; Router::$segments = NULL; Router::$url_suffix = ''; }
/** * Instantiates the specified controller, optionally replacing $_GET and $_POST contents before calling the component constructor. * \note The original $_GET and $_POST array are restored as soon as the component is instantiated. * @param $controller The name of the controller class to be instantiated, lowercase, without the "Controller_" prefix. * @param $get The array that should replace $_GET. * @param $post The array that should replace $_POST. * @return A new Component object. */ public static function factory($controller, $get = null, $post = null) { // Backup router state $old_router = array(); $old_router['current_route'] = Router::$current_route; $old_router['current_uri'] = Router::$current_uri; $old_router['query_string'] = Router::$query_string; $old_router['complete_uri'] = Router::$complete_uri; $old_router['controller'] = Router::$controller; $old_router['method'] = Router::$method; $old_router['arguments'] = Router::$arguments; // The following three variables could be determined by running Router code and passing an url, but: // 1) The performance penalty would be high // 1) It's not a good idea for a controller to alter its behaviour depending on them, anyway //Router::$current_route = ''; //Router::$current_uri = ''; //Router::$complete_uri = ''; Router::$controller = $controller; // We don't know these yet Router::$method = ''; Router::$arguments = array(); // If get or post parameters are passed, alter $_GET, $_POST and Router::$query_string accordingly // NOTE: Should we alter $_SERVER['QUERY_STRING'] too? if ($get !== null) { $old_get = $_GET; $_GET = $get; Router::$query_string = '?' . http_build_query($get); } if ($post !== null) { $old_post = $_POST; $_POST = $post; } // If class is not defined already, load controller file $controller_class = 'Controller_' . ucfirst($controller); if (!class_exists($controller_class, false)) { $controller_file = str_replace('_', '/', strtolower($controller_class)); // If the component file doesn't exist, fire exception $filepath = Kohana::find_file('classes', $controller_file, true); // Include the Controller file require_once $filepath; } // Run system.pre_controller Event::run('dispatch.pre_controller'); // Initialize the controller $controller_instance = new $controller_class(); // Run system.post_controller_constructor Event::run('dispatch.post_controller_constructor'); // Revert $_GET and $_POST changes if ($get !== null) { $_GET = $old_get; } if ($post !== null) { $_POST = $old_post; } // Revert Router state Router::$current_route = $old_router['current_route']; Router::$current_uri = $old_router['current_uri']; Router::$query_string = $old_router['query_string']; Router::$complete_uri = $old_router['complete_uri']; Router::$controller = $old_router['controller']; Router::$method = $old_router['method']; Router::$arguments = $old_router['arguments']; return new Component($controller_instance, $controller, $old_router); }
/** * Router setup routine. Automatically called during Kohana setup process. * * @return void */ public static function setup() { if (!empty($_SERVER['QUERY_STRING'])) { // Set the query string to the current query string Router::$query_string = '?' . trim($_SERVER['QUERY_STRING'], '&/'); } if (Router::$routes === NULL) { // Load routes Router::$routes = Kohana::config('routes'); } // Default route status $default_route = FALSE; if (Router::$current_uri === '') { // Make sure the default route is set if (!isset(Router::$routes['_default'])) { throw new Kohana_Exception('core.no_default_route'); } // Use the default route when no segments exist Router::$current_uri = Router::$routes['_default']; // Default route is in use $default_route = TRUE; } // Make sure the URL is not tainted with HTML characters Router::$current_uri = html::specialchars(Router::$current_uri, FALSE); // Remove all dot-paths from the URI, they are not valid Router::$current_uri = preg_replace('#\\.[\\s./]*/#', '', Router::$current_uri); // At this point segments, rsegments, and current URI are all the same Router::$segments = Router::$rsegments = Router::$current_uri = trim(Router::$current_uri, '/'); // Set the complete URI Router::$complete_uri = Router::$current_uri . Router::$query_string; // Explode the segments by slashes Router::$segments = ($default_route === TRUE or Router::$segments === '') ? array() : explode('/', Router::$segments); if ($default_route === FALSE and count(Router::$routes) > 1) { // Custom routing Router::$rsegments = Router::routed_uri(Router::$current_uri); } // The routed URI is now complete Router::$routed_uri = Router::$rsegments; // Routed segments will never be empty Router::$rsegments = explode('/', Router::$rsegments); // Prepare to find the controller $controller_path = ''; $method_segment = NULL; // Paths to search $paths = Kohana::include_paths(); foreach (Router::$rsegments as $key => $segment) { // Add the segment to the search path $controller_path .= $segment; $found = FALSE; foreach ($paths as $dir) { // Search within controllers only $dir .= 'controllers/'; if (is_dir($dir . $controller_path) or is_file($dir . $controller_path . EXT)) { // Valid path $found = TRUE; // The controller must be a file that exists with the search path if ($c = str_replace('\\', '/', realpath($dir . $controller_path . EXT)) and is_file($c) and strpos($c, $dir) === 0) { // Set controller name Router::$controller = $segment; // Change controller path Router::$controller_path = $c; // Set the method segment $method_segment = $key + 1; // Stop searching break; } } } if ($found === FALSE) { // Maximum depth has been reached, stop searching break; } // Add another slash $controller_path .= '/'; } if ($method_segment !== NULL and isset(Router::$rsegments[$method_segment])) { // Set method Router::$method = Router::$rsegments[$method_segment]; if (isset(Router::$rsegments[$method_segment + 1])) { // Set arguments Router::$arguments = array_slice(Router::$rsegments, $method_segment + 1); } } // Last chance to set routing before a 404 is triggered Event::run('system.post_routing'); if (Router::$controller === NULL) { // No controller was found, so no page can be rendered Event::run('system.404'); } }