Skip to content
Snippets Groups Projects
Commit 084d8361 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

ensure all set parameters are correctly transfered to trails by replacing use...

ensure all set parameters are correctly transfered to trails by replacing use PATH_INFO with correct destructuring of REQUEST_URI and provide according tests, fixes #2030

Closes #2030

Merge request studip/studip!1329
parent 0313846a
No related branches found
No related tags found
No related merge requests found
......@@ -131,6 +131,33 @@ class Request implements ArrayAccess, IteratorAggregate
return $_SERVER['REQUEST_URI'];
}
/**
* Return the filename of the currently executing script.
* @return string
*/
public static function script_name(): string
{
return $_SERVER['SCRIPT_NAME'];
}
/**
* Returns the complete path info including duplicated slashes.
* $_SERVER['PATH_INFO'] will remove them.
*/
public static function path_info(): string
{
$script_name = self::script_name();
$script_name = preg_quote($script_name, '#');
$script_name = str_replace('/', '/+', $script_name);
$path_info = preg_replace(
"#^{$script_name}#",
'',
urldecode(self::path())
);
return parse_url($path_info, PHP_URL_PATH);
}
/**
* Set the selected query parameter to a specific value.
*
......@@ -715,7 +742,7 @@ class Request implements ArrayAccess, IteratorAggregate
$extract[] = array_values(array_filter(array_map('trim', explode(' ', $one))));
}
foreach ($extract as $one) {
list($param, $func) = $one;
[$param, $func] = $one;
if (!$func) {
$func = 'get';
}
......
......@@ -523,7 +523,7 @@ class Router
private function normalizeDispatchURI($uri)
{
return $uri === null ? $_SERVER['PATH_INFO'] : $uri;
return $uri ?? \Request::path_info();
}
private function normalizeRequestMethod($method)
......
......@@ -30,6 +30,7 @@ namespace {
}
namespace RESTAPI {
use Config;
// A potential api exception will lead to an according response with the
......@@ -44,7 +45,7 @@ namespace RESTAPI {
// Initialize RESTAPI plugins
\PluginEngine::getPlugins('RESTAPIPlugin');
$uri = $_SERVER['PATH_INFO'];
$uri = \Request::path_info();
// Check version
if (defined('RESTAPI\\VERSION') && preg_match('~^/v(\d+)~i', $uri, $match)) {
......
......@@ -15,7 +15,7 @@
require_once '../lib/bootstrap.php';
// Obtain request information
$uri = ltrim($_SERVER['PATH_INFO'], '/');
$uri = ltrim(Request::path_info(), '/');
list($type, $id) = explode('/', $uri, 2);
// Setup response
......
......@@ -21,7 +21,5 @@ require '../lib/bootstrap.php';
// prepare environment
URLHelper::setBaseUrl($GLOBALS['ABSOLUTE_URI_STUDIP']);
$request_uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
$dispatcher = app(\Trails_Dispatcher::class);
$dispatcher->dispatch($request_uri);
$dispatcher->dispatch(Request::path_info());
......@@ -55,7 +55,7 @@ if (!function_exists('_')) {
$GLOBALS['template_factory'] = new Flexi_TemplateFactory('../templates/');
# get plugin class from request
$dispatch_to = $_SERVER['PATH_INFO'] ?: '';
$dispatch_to = ltrim(Request::path_info(), '/');
$dispatcher = new Trails_Dispatcher( '../app', $_SERVER['SCRIPT_NAME'], 'admin/install');
$dispatcher->dispatch("admin/install/{$dispatch_to}");
......@@ -27,7 +27,7 @@ try {
require_once 'lib/seminar_open.php';
// get plugin class from request
$dispatch_to = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
$dispatch_to = Request::path_info();
list($plugin_class, $unconsumed) = PluginEngine::routeRequest($dispatch_to);
// handle legacy forum plugin URLs
......
......@@ -34,7 +34,7 @@ $_language_path = init_i18n($_SESSION['_language']);
$GLOBALS['template_factory'] = new Flexi_TemplateFactory('../templates/');
# get plugin class from request
$dispatch_to = $_SERVER['PATH_INFO'] ?: '';
$dispatch_to = Request::path_info() ?: '';
$dispatcher = app(\Trails_Dispatcher::class);
$dispatcher->trails_uri = $_SERVER['SCRIPT_NAME'];
......
......@@ -73,4 +73,18 @@ class FunctionsTest extends \Codeception\Test\Unit
$output = 'https://m%C3%A4uschen-h%C3%BCpft.de/%C3%B6ffnungszeiten?menu=Spa%C3%9F&page=23';
$this->assertEquals($output, encodeURI($input));
}
/**
* @covers Trails_Controller::extract_action_and_args()
*/
public function testTrailsControllerExtractActionAndArgs()
{
$controller = new Trails_Controller(null);
list($action, $args, $format) = $controller->extract_action_and_args('foo/bar//42.html');
$this->assertEquals('foo', $action);
$this->assertEquals(['bar', '', '42'], $args);
$this->assertEquals('html', $format);
}
}
<?php
/**
* @backupGlobals enabled
*/
class RequestMethodTest extends \Codeception\Test\Unit
{
public function setUp(): void
{
unset($_SERVER['REQUEST_METHOD']);
unset($_SERVER['HTTP_X_REQUESTED_WITH']);
}
protected function setRequestMethod($method)
{
$_SERVER['REQUEST_METHOD'] = (string)$method;
}
public function testMethod()
{
$this->setRequestMethod('GET');
$this->assertEquals('GET', Request::method());
}
public function testMethodUppercases()
{
$this->setRequestMethod('gEt');
$this->assertEquals('GET', Request::method());
}
public function testRequestMethodGet()
{
$this->setRequestMethod('GET');
$this->assertTrue(Request::isGet());
}
public function testRequestMethodPost()
{
$this->setRequestMethod('POST');
$this->assertTrue(Request::isPost());
}
public function testRequestMethodPut()
{
$this->setRequestMethod('PUT');
$this->assertTrue(Request::isPut());
}
public function testRequestMethodDelete()
{
$this->setRequestMethod('DELETE');
$this->assertTrue(Request::isDelete());
}
public function testIsNotXhr()
{
$this->assertFalse(Request::isXhr());
$this->assertFalse(Request::isAjax());
}
public function testIsXhr()
{
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XmlHttpRequest';
$this->assertTrue(Request::isAjax());
$this->assertTrue(Request::isXhr());
}
}
<?php
/*
* RequestParametersTest.php - unit tests for the Request class handling of
* parameters.
*
* Copyright (c) 2009 Elmar Ludwig
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
/**
* @backupGlobals enabled
*/
class RequestParametersTest extends Codeception\Test\Unit
{
public function setUp (): void
{
$_GET['a'] = 'test';
$_POST['b'] = '\\h1"';
$_GET['c'] = '-23';
$_POST['d'] = '12.7';
$_GET['e'] = '3,14';
$_POST['s_x'] = '0';
$_GET['f'] = 'root@studip';
$_POST['g'] = '1';
$_GET['h'] = '';
$_GET['v1'] = ['1', '2.4', '3,7'];
$_POST['v2'] = ['on\'e', 'two', 'thr33'];
$_GET['v3'] = ['root@studip', 'hotte.testfreund', 42, '!"$%&/()'];
$_POST['v4'] = ['0', '1', '', 'foo'];
$testconfig = new Config([
'USERNAME_REGULAR_EXPRESSION' => '/^([a-zA-Z0-9_@.-]{4,})$/',
]);
Config::set($testconfig);
}
public function testArrayAccess ()
{
$request = Request::getInstance();
$this->assertNull($request['null']);
$this->assertSame($request['a'], 'test');
$this->assertSame($request['b'], '\\h1"');
$this->assertSame($request['c'], '-23');
}
public function testSetParam ()
{
Request::set('yyy', 'xyzzy');
Request::set('zzz', [1, 2]);
$this->assertSame(Request::get('yyy'), 'xyzzy');
$this->assertSame(Request::getArray('zzz'), [1, 2]);
}
public function testStringParam ()
{
$this->assertNull(Request::get('null'));
$this->assertSame(Request::get('null', 'foo'), 'foo');
$this->assertSame(Request::get('a'), 'test');
$this->assertSame(Request::get('b'), '\\h1"');
$this->assertSame(Request::get('c'), '-23');
$this->assertSame(Request::get('d'), '12.7');
$this->assertNull(Request::get('v2'));
$this->assertNull(Request::quoted('null'));
$this->assertSame(Request::quoted('null', 'foo'), 'foo');
$this->assertSame(Request::quoted('b'), '\\\\h1\\"');
$this->assertNull(Request::quoted('v2'));
}
public function testOptionParam ()
{
$this->assertNull(Request::option('null'));
$this->assertSame(Request::option('a'), 'test');
$this->assertNull(Request::option('b'));
$this->assertNull(Request::option('v1'));
}
public function testIntParam ()
{
$this->assertNull(Request::int('null'));
$this->assertSame(Request::int('a'), 0);
$this->assertSame(Request::int('c'), -23);
$this->assertSame(Request::int('d'), 12);
$this->assertSame(Request::int('e'), 3);
$this->assertNull(Request::int('v1'));
}
public function testFloatParam ()
{
$this->assertNull(Request::float('null'));
$this->assertSame(Request::float('a'), 0.0);
$this->assertSame(Request::float('c'), -23.0);
$this->assertSame(Request::float('d'), 12.7);
$this->assertSame(Request::float('e'), 3.14);
$this->assertNull(Request::float('v1'));
}
public function testBoolParam ()
{
$this->assertNull(Request::bool('null'));
$this->assertTrue(Request::bool('a'));
$this->assertTrue(Request::bool('c'));
$this->assertTrue(Request::bool('d'));
$this->assertTrue(Request::bool('e'));
$this->assertTrue(Request::bool('g'));
$this->assertFalse(Request::bool('h'));
$this->assertFalse(Request::bool('s_x'));
$this->assertNull(Request::bool('v1'));
}
public function testUsernameParam ()
{
$this->assertNull(Request::username('null'));
$this->assertSame(Request::username('a'), 'test');
$this->assertSame(Request::username('f'), 'root@studip');
$this->assertNull(Request::username('b'));
$this->assertNull(Request::username('v1'));
}
public function testStringArrayParam ()
{
$this->assertSame(Request::getArray('null'), []);
$this->assertSame(Request::getArray('b'), []);
$this->assertSame(Request::getArray('v1'), ['1', '2.4', '3,7']);
$this->assertSame(Request::getArray('v2'), ['on\'e', 'two', 'thr33']);
$this->assertSame(Request::quotedArray('null'), []);
$this->assertSame(Request::quotedArray('b'), []);
$this->assertSame(Request::quotedArray('v1'), ['1', '2.4', '3,7']);
$this->assertSame(Request::quotedArray('v2'), ['on\\\'e', 'two', 'thr33']);
}
public function testOptionArrayParam ()
{
$this->assertSame(Request::optionArray('null'), []);
$this->assertSame(Request::optionArray('a'), []);
$this->assertSame(Request::optionArray('v1'), ['1']);
$this->assertSame(Request::optionArray('v2'), [1 => 'two', 2 => 'thr33']);
}
public function testIntArrayParam ()
{
$this->assertSame(Request::intArray('null'), []);
$this->assertSame(Request::intArray('c'), []);
$this->assertSame(Request::intArray('v1'), [1, 2, 3]);
$this->assertSame(Request::intArray('v2'), [0, 0, 0]);
}
public function testFloatArrayParam ()
{
$this->assertSame(Request::floatArray('null'), []);
$this->assertSame(Request::floatArray('c'), []);
$this->assertSame(Request::floatArray('v1'), [1.0, 2.4, 3.7]);
$this->assertSame(Request::floatArray('v2'), [0.0, 0.0, 0.0]);
}
public function testBoolArrayParam ()
{
$this->assertSame(Request::boolArray('null'), []);
$this->assertSame(Request::boolArray('c'), []);
$this->assertSame(Request::boolArray('v4'), [false, true, false, true]);
}
public function testUsernameArrayParam ()
{
$this->assertSame(Request::usernameArray('null'), []);
$this->assertSame(Request::usernameArray('a'), []);
$this->assertSame(Request::usernameArray('v1'), []);
$this->assertSame(Request::usernameArray('v2'), [2 => 'thr33']);
$this->assertSame(Request::usernameArray('v3'), ['root@studip', 'hotte.testfreund']);
}
public function testSubmitted ()
{
$this->assertFalse(Request::submitted('null'));
$this->assertTrue(Request::submitted('s'));
$this->assertTrue(Request::submitted('v1'));
}
public function testSubmittedSome ()
{
$this->assertFalse(Request::submittedSome('null', 'null'));
$this->assertTrue(Request::submittedSome('null', 's', 'v'));
}
public function tearDown(): void
{
Config::set(null);
}
}
......@@ -10,264 +10,137 @@
* the License, or (at your option) any later version.
*/
/**
* @backupGlobals enabled
*/
class RequestTest extends \Codeception\Test\Unit
{
public function setUp(): void
{
$_GET['a'] = 'test';
$_POST['b'] = '\\h1"';
$_GET['c'] = '-23';
$_POST['d'] = '12.7';
$_GET['e'] = '3,14';
$_POST['s_x'] = '0';
$_GET['f'] = 'root@studip';
$_POST['g'] = '1';
$_GET['h'] = '';
$_GET['v1'] = ['1', '2.4', '3,7'];
$_POST['v2'] = ['on\'e', 'two', 'thr33'];
$_GET['v3'] = ['root@studip', 'hotte.testfreund', 42, '!"$%&/()'];
$_POST['v4'] = ['0', '1', '', 'foo'];
$testconfig = new Config([
'USERNAME_REGULAR_EXPRESSION' => '/^([a-zA-Z0-9_@.-]{4,})$/',
]);
Config::set($testconfig);
unset($_SERVER['HTTPS']);
unset($_SERVER['HTTP_X_FORWARDED_PROTO']);
unset($_SERVER['REQUEST_URI']);
unset($_SERVER['SCRIPT_NAME']);
unset($_SERVER['SERVER_NAME']);
unset($_SERVER['SERVER_PORT']);
}
public function testURL ()
protected function setScriptName(string $script_name): void
{
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_NAME'] = 'www.example.com';
$_SERVER['SERVER_PORT'] = '443';
$_SERVER['REQUEST_URI'] = '/do/it?now=1';
$this->assertEquals('https://www.example.com/do/it?now=1', Request::url());
$_SERVER['HTTPS'] = '';
$_SERVER['SERVER_NAME'] = 'www.example.com';
$_SERVER['SERVER_PORT'] = '8080';
$_SERVER['REQUEST_URI'] = '/index.php';
$this->assertEquals('http://www.example.com:8080/index.php', Request::url());
$_SERVER['SCRIPT_NAME'] = $script_name;
}
public function testArrayAccess ()
protected function setRequestUri(string $request_uri): void
{
$request = Request::getInstance();
$this->assertNull($request['null']);
$this->assertSame($request['a'], 'test');
$this->assertSame($request['b'], '\\h1"');
$this->assertSame($request['c'], '-23');
}
public function testSetParam ()
{
Request::set('yyy', 'xyzzy');
Request::set('zzz', [1, 2]);
$this->assertSame(Request::get('yyy'), 'xyzzy');
$this->assertSame(Request::getArray('zzz'), [1, 2]);
}
public function testStringParam ()
{
$this->assertNull(Request::get('null'));
$this->assertSame(Request::get('null', 'foo'), 'foo');
$this->assertSame(Request::get('a'), 'test');
$this->assertSame(Request::get('b'), '\\h1"');
$this->assertSame(Request::get('c'), '-23');
$this->assertSame(Request::get('d'), '12.7');
$this->assertNull(Request::get('v2'));
$this->assertNull(Request::quoted('null'));
$this->assertSame(Request::quoted('null', 'foo'), 'foo');
$this->assertSame(Request::quoted('b'), '\\\\h1\\"');
$this->assertNull(Request::quoted('v2'));
}
public function testOptionParam ()
{
$this->assertNull(Request::option('null'));
$this->assertSame(Request::option('a'), 'test');
$this->assertNull(Request::option('b'));
$this->assertNull(Request::option('v1'));
}
public function testIntParam ()
{
$this->assertNull(Request::int('null'));
$this->assertSame(Request::int('a'), 0);
$this->assertSame(Request::int('c'), -23);
$this->assertSame(Request::int('d'), 12);
$this->assertSame(Request::int('e'), 3);
$this->assertNull(Request::int('v1'));
}
public function testFloatParam ()
{
$this->assertNull(Request::float('null'));
$this->assertSame(Request::float('a'), 0.0);
$this->assertSame(Request::float('c'), -23.0);
$this->assertSame(Request::float('d'), 12.7);
$this->assertSame(Request::float('e'), 3.14);
$this->assertNull(Request::float('v1'));
}
public function testBoolParam ()
{
$this->assertNull(Request::bool('null'));
$this->assertTrue(Request::bool('a'));
$this->assertTrue(Request::bool('c'));
$this->assertTrue(Request::bool('d'));
$this->assertTrue(Request::bool('e'));
$this->assertTrue(Request::bool('g'));
$this->assertFalse(Request::bool('h'));
$this->assertFalse(Request::bool('s_x'));
$this->assertNull(Request::bool('v1'));
}
public function testUsernameParam ()
{
$this->assertNull(Request::username('null'));
$this->assertSame(Request::username('a'), 'test');
$this->assertSame(Request::username('f'), 'root@studip');
$this->assertNull(Request::username('b'));
$this->assertNull(Request::username('v1'));
}
public function testStringArrayParam ()
{
$this->assertSame(Request::getArray('null'), []);
$this->assertSame(Request::getArray('b'), []);
$this->assertSame(Request::getArray('v1'), ['1', '2.4', '3,7']);
$this->assertSame(Request::getArray('v2'), ['on\'e', 'two', 'thr33']);
$this->assertSame(Request::quotedArray('null'), []);
$this->assertSame(Request::quotedArray('b'), []);
$this->assertSame(Request::quotedArray('v1'), ['1', '2.4', '3,7']);
$this->assertSame(Request::quotedArray('v2'), ['on\\\'e', 'two', 'thr33']);
$_SERVER['REQUEST_URI'] = $request_uri;
}
public function testOptionArrayParam ()
protected function setServerNameAndPort(string $name, int $port, bool $ssl = false): void
{
$this->assertSame(Request::optionArray('null'), []);
$this->assertSame(Request::optionArray('a'), []);
$this->assertSame(Request::optionArray('v1'), ['1']);
$this->assertSame(Request::optionArray('v2'), [1 => 'two', 2 => 'thr33']);
$_SERVER['SERVER_NAME'] = $name;
$_SERVER['SERVER_PORT'] = $port;
$_SERVER['HTTPS'] = $ssl ? 'on' : 'off';
}
public function testIntArrayParam ()
{
$this->assertSame(Request::intArray('null'), []);
$this->assertSame(Request::intArray('c'), []);
$this->assertSame(Request::intArray('v1'), [1, 2, 3]);
$this->assertSame(Request::intArray('v2'), [0, 0, 0]);
}
public function testFloatArrayParam ()
{
$this->assertSame(Request::floatArray('null'), []);
$this->assertSame(Request::floatArray('c'), []);
$this->assertSame(Request::floatArray('v1'), [1.0, 2.4, 3.7]);
$this->assertSame(Request::floatArray('v2'), [0.0, 0.0, 0.0]);
}
public function testBoolArrayParam ()
/**
* @covers Request::protocol
*/
public function testProtocol(): void
{
$this->assertSame(Request::boolArray('null'), []);
$this->assertSame(Request::boolArray('c'), []);
$this->assertSame(Request::boolArray('v4'), [false, true, false, true]);
}
$this->assertEquals('http', Request::protocol());
public function testUsernameArrayParam ()
{
$this->assertSame(Request::usernameArray('null'), []);
$this->assertSame(Request::usernameArray('a'), []);
$this->assertSame(Request::usernameArray('v1'), []);
$this->assertSame(Request::usernameArray('v2'), [2 => 'thr33']);
$this->assertSame(Request::usernameArray('v3'), ['root@studip', 'hotte.testfreund']);
}
$_SERVER['HTTPS'] = 'on';
$this->assertEquals('https', Request::protocol());
public function testSubmitted ()
{
$this->assertFalse(Request::submitted('null'));
$this->assertTrue(Request::submitted('s'));
$this->assertTrue(Request::submitted('v1'));
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'foo';
$this->assertEquals('foo', Request::protocol());
}
public function testSubmittedSome ()
/**
* @covers Request::server
*/
public function testServer(): void
{
$this->assertFalse(Request::submittedSome('null', 'null'));
$this->assertTrue(Request::submittedSome('null', 's', 'v'));
}
// Usual ports for http and https
$this->setServerNameAndPort('www.studip.de', 80);
$this->assertEquals('www.studip.de', Request::server());
public function tearDown(): void
{
Config::set(null);
}
}
$this->setServerNameAndPort('www.studip.de', 443, true);
$this->assertEquals('www.studip.de', Request::server());
class RequestMethodTest extends \Codeception\Test\Unit
{
public function setUp (): void
{
unset($_SERVER['REQUEST_METHOD']);
unset($_SERVER['HTTP_X_REQUESTED_WITH']);
}
// Unusual ports for http and https
$this->setServerNameAndPort('www.studip.de', 80, true);
$this->assertEquals('www.studip.de:80', Request::server());
protected function setRequestMethod($method)
{
$_SERVER['REQUEST_METHOD'] = (string) $method;
}
$this->setServerNameAndPort('www.studip.de', 443, false);
$this->assertEquals('www.studip.de:443', Request::server());
public function testMethod()
{
$this->setRequestMethod('GET');
$this->assertEquals('GET', Request::method());
}
// Other tests
$this->setServerNameAndPort('www.studip.de', 8088);
$this->assertEquals('www.studip.de:8088', Request::server());
public function testMethodUppercases()
{
$this->setRequestMethod('gEt');
$this->assertEquals('GET', Request::method());
$this->setServerNameAndPort('www.studip.de', 8088, true);
$this->assertEquals('www.studip.de:8088', Request::server());
}
public function testRequestMethodGet()
/**
* @covers Request::path()
*/
public function testPath(): void
{
$this->setRequestMethod('GET');
$this->assertTrue(Request::isGet());
$this->setRequestUri('/foo');
$this->assertEquals('/foo', Request::path());
}
public function testRequestMethodPost()
/**
* @depends testProtocol
* @depends testServer
* @depends testPath
* @covers Request::url
*/
public function testURL(): void
{
$this->setRequestMethod('POST');
$this->assertTrue(Request::isPost());
}
$this->setServerNameAndPort('www.example.com', 443, true);
$this->setRequestUri('/do/it?now=1');
$this->assertEquals('https://www.example.com/do/it?now=1', Request::url());
public function testRequestMethodPut()
{
$this->setRequestMethod('PUT');
$this->assertTrue(Request::isPut());
$this->setServerNameAndPort('www.example.com', 8080);
$this->setRequestUri('/index.php');
$this->assertEquals('http://www.example.com:8080/index.php', Request::url());
}
public function testRequestMethodDelete()
public function testScriptName(): void
{
$this->setRequestMethod('DELETE');
$this->assertTrue(Request::isDelete());
$this->setScriptName('/index.php');
$this->assertEquals('/index.php', Request::script_name());
}
public function testIsNotXhr()
/**
* @depends testPath
* @depends testScriptName
* @covers Request::path_info
* @dataProvider PathProvider
*/
public function testPathInfo(string $request_uri, string $script_name, string $expected): void
{
$this->assertFalse(Request::isXhr());
$this->assertFalse(Request::isAjax());
$this->setScriptName($script_name);
$this->setRequestUri($request_uri);
$this->assertEquals($expected, Request::path_info());
}
public function testIsXhr()
{
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XmlHttpRequest';
$this->assertTrue(Request::isAjax());
$this->assertTrue(Request::isXhr());
/**
* Data provider for testGetCompletePathInfo
*
* @return array[]
* @see RequestTest::testPathInfo
*/
public function PathProvider(): array
{
return [
'Regular' => ['/studip/dispatch.php/start', '/studip/dispatch.php', '/start'],
'With duplicate slash' => ['/plugins.php/foo/bar//42', '/plugins.php', '/foo/bar//42'],
'With duplicate slashes' => ['/bogus.php/1/2//4///7///', '/bogus.php', '/1/2//4///7///'],
'Encoded' => ['/dispatch.php/%62lu%62%62er', '/dispatch.php', '/blubber'],
];
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment