Add tests for MD_STD_IN::sanitize_url() and ensure it supports rewriting
unencoded cyrillic inputs Close #7
This commit is contained in:
parent
2176e7312b
commit
ae12cfdf0f
16
phpunit.xml
Normal file
16
phpunit.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||||
|
backupGlobals="false" backupStaticAttributes="false"
|
||||||
|
beStrictAboutChangesToGlobalState="true" beStrictAboutOutputDuringTests="false" beStrictAboutResourceUsageDuringSmallTests="true" beStrictAboutTodoAnnotatedTests="true" beStrictAboutCoversAnnotation="false"
|
||||||
|
bootstrap="tests/bootstrap.php"
|
||||||
|
cacheResult="false"
|
||||||
|
colors="true"
|
||||||
|
convertErrorsToExceptions="true" convertDeprecationsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true"
|
||||||
|
enforceTimeLimit="true"
|
||||||
|
failOnWarning="true"
|
||||||
|
forceCoversAnnotation="false"
|
||||||
|
printerClass="Codedungeon\PHPUnitPrettyResultPrinter\Printer" processIsolation="true"
|
||||||
|
stopOnError="true" stopOnFailure="true" stopOnIncomplete="true" stopOnSkipped="true" stopOnRisky="true"
|
||||||
|
timeoutForSmallTests="1" timeoutForMediumTests="10" timeoutForLargeTests="60"
|
||||||
|
verbose="true">
|
||||||
|
</phpunit>
|
@ -197,13 +197,30 @@ final class MD_STD_IN {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = \filter_var($input, FILTER_SANITIZE_URL);
|
try {
|
||||||
if (($output = \filter_var($output, FILTER_VALIDATE_URL)) === false) {
|
if (($output = \filter_var($input, FILTER_VALIDATE_URL)) === false) {
|
||||||
throw new MDInvalidUrl("Invalid input URL");
|
throw new MDInvalidUrl("Invalid input URL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MDInvalidUrl $e) {
|
||||||
|
if (($parsed = parse_url($input)) === false || empty($parsed['scheme'])) {
|
||||||
|
throw new MDInvalidUrl("Invalid input URL");
|
||||||
|
}
|
||||||
|
$rewritten = $parsed['scheme'] . '://';
|
||||||
|
if (!empty($parsed['user']) && !empty($parsed['pass'])) {
|
||||||
|
$rewritten .= $parsed['user'] . ':' . $parsed['pass'] . '@';
|
||||||
|
}
|
||||||
|
$rewritten .= $parsed['host'];
|
||||||
|
if (!empty($parsed['port'])) $rewritten .= ':' . $parsed['port'];
|
||||||
|
$rewritten .= str_replace('%2F' , '/', urlencode($parsed['path']));
|
||||||
|
if (!empty($parsed['query'])) $rewritten .= '?' . urlencode($parsed['query']);
|
||||||
|
if (($output = \filter_var($rewritten, FILTER_VALIDATE_URL)) === false) {
|
||||||
|
throw new MDInvalidUrl("Invalid input URL" . \urlencode($input));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for valid schemes
|
// Check for valid schemes
|
||||||
if (MD_STD::startsWithAny($input, ['https://', 'http://', 'ftp://']) === false) {
|
if (MD_STD::startsWithAny($output, ['https://', 'http://', 'ftp://']) === false) {
|
||||||
throw new MDInvalidUrl("Invalid input URL");
|
throw new MDInvalidUrl("Invalid input URL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
tests/MD_STD_IN_Test.php
Normal file
37
tests/MD_STD_IN_Test.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?PHP
|
||||||
|
/**
|
||||||
|
* Tests for MD_STD_IN.
|
||||||
|
*
|
||||||
|
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||||
|
*/
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for MD_STD_IN.
|
||||||
|
*/
|
||||||
|
final class MD_STD_IN_Test extends TestCase {
|
||||||
|
/**
|
||||||
|
* Function for testing sanitize_url().
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSanitizeUrlWorksBasically():void {
|
||||||
|
|
||||||
|
// Ensure empty inputs return empty output
|
||||||
|
self::assertEquals("", MD_STD_IN::sanitize_url(""));
|
||||||
|
self::assertEquals("https://www.museum-digital.org", MD_STD_IN::sanitize_url("https://www.museum-digital.org"));
|
||||||
|
|
||||||
|
// Ensure that cyrillic characters are accepted
|
||||||
|
self::assertEquals("https://sr.wikipedia.org/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4", MD_STD_IN::sanitize_url("https://sr.wikipedia.org/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4"));
|
||||||
|
self::assertEquals("https://sr.wikipedia.org/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4", MD_STD_IN::sanitize_url("https://sr.wikipedia.org/wiki/Београд"));
|
||||||
|
|
||||||
|
self::assertEquals("https://username:password@sr.wikipedia.org:9000/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4", MD_STD_IN::sanitize_url("https://username:password@sr.wikipedia.org:9000/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4"));
|
||||||
|
self::assertEquals("https://username:password@sr.wikipedia.org:9000/wiki/%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4", MD_STD_IN::sanitize_url("https://username:password@sr.wikipedia.org:9000/wiki/Београд"));
|
||||||
|
|
||||||
|
self::expectException(MDInvalidUrl::class);
|
||||||
|
MD_STD_IN::sanitize_url("h ttps://www.museum-digital.org");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
tests/bootstrap.php
Normal file
25
tests/bootstrap.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?PHP
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autoloader for musdb.
|
||||||
|
*
|
||||||
|
* @param string $className Name of the class to load.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
\spl_autoload_register(function(string $className):void {
|
||||||
|
|
||||||
|
// Try using class map as defined through /scripts/buildClassMap.php
|
||||||
|
|
||||||
|
foreach (array_merge([__DIR__ . '/../tests', __DIR__ . '/../src', __DIR__ . '/../../MDErrorReporter', __DIR__ . '/../../MDErrorReporter/exceptions', __DIR__ . '/../../MDErrorReporter/exceptions/generic', __DIR__ . '/../../MDErrorReporter/exceptions/updates']) as $classDir) {
|
||||||
|
|
||||||
|
if (\file_exists("$classDir/$className.php")) {
|
||||||
|
include "$classDir/$className.php";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user