mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Move url sanitisation out of Element class
This commit is contained in:
parent
a681cf631c
commit
41fb6b0d43
@ -8,6 +8,7 @@ use Erusev\Parsedown\Components\Inline;
|
||||
use Erusev\Parsedown\Configurables\SafeMode;
|
||||
use Erusev\Parsedown\Html\Renderables\Element;
|
||||
use Erusev\Parsedown\Html\Renderables\Text;
|
||||
use Erusev\Parsedown\Html\Sanitisation\UrlSanitiser;
|
||||
use Erusev\Parsedown\Parsedown;
|
||||
use Erusev\Parsedown\Parsing\Excerpt;
|
||||
use Erusev\Parsedown\State;
|
||||
@ -84,7 +85,7 @@ final class Image implements Inline
|
||||
}
|
||||
|
||||
if ($State->get(SafeMode::class)->isEnabled()) {
|
||||
$attributes['src'] = Element::filterUnsafeUrl($attributes['src']);
|
||||
$attributes['src'] = UrlSanitiser::filter($attributes['src']);
|
||||
}
|
||||
|
||||
return Element::selfClosing('img', $attributes);
|
||||
|
@ -10,6 +10,7 @@ use Erusev\Parsedown\Configurables\InlineTypes;
|
||||
use Erusev\Parsedown\Configurables\SafeMode;
|
||||
use Erusev\Parsedown\Html\Renderables\Element;
|
||||
use Erusev\Parsedown\Html\Renderables\Text;
|
||||
use Erusev\Parsedown\Html\Sanitisation\UrlSanitiser;
|
||||
use Erusev\Parsedown\Parsedown;
|
||||
use Erusev\Parsedown\Parsing\Excerpt;
|
||||
use Erusev\Parsedown\State;
|
||||
@ -124,7 +125,7 @@ final class Link implements Inline
|
||||
}
|
||||
|
||||
if ($State->get(SafeMode::class)->isEnabled()) {
|
||||
$attributes['href'] = Element::filterUnsafeUrl($attributes['href']);
|
||||
$attributes['href'] = UrlSanitiser::filter($attributes['href']);
|
||||
}
|
||||
|
||||
$State = $State->setting(
|
||||
|
@ -62,25 +62,6 @@ final class Element implements Renderable
|
||||
'basefont' => true,
|
||||
];
|
||||
|
||||
/** @var string[] */
|
||||
public static $COMMON_SCHEMES = [
|
||||
'http://',
|
||||
'https://',
|
||||
'ftp://',
|
||||
'ftps://',
|
||||
'mailto:',
|
||||
'tel:',
|
||||
'data:image/png;base64,',
|
||||
'data:image/gif;base64,',
|
||||
'data:image/jpeg;base64,',
|
||||
'irc:',
|
||||
'ircs:',
|
||||
'git:',
|
||||
'ssh:',
|
||||
'news:',
|
||||
'steam:',
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
@ -224,40 +205,4 @@ final class Element implements Renderable
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string[]|null $permittedSchemes
|
||||
* @return string
|
||||
*/
|
||||
public static function filterUnsafeUrl($url, $permittedSchemes = null)
|
||||
{
|
||||
if (! isset($permittedSchemes)) {
|
||||
$permittedSchemes = self::$COMMON_SCHEMES;
|
||||
}
|
||||
|
||||
foreach ($permittedSchemes as $scheme) {
|
||||
if (self::striAtStart($url, $scheme)) {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
return \str_replace(':', '%3A', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param string $needle
|
||||
* @return bool
|
||||
*/
|
||||
private static function striAtStart($string, $needle)
|
||||
{
|
||||
$len = \strlen($needle);
|
||||
|
||||
if ($len > \strlen($string)) {
|
||||
return false;
|
||||
} else {
|
||||
return \strtolower(\substr($string, 0, $len)) === \strtolower($needle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
63
src/Html/Sanitisation/UrlSanitiser.php
Normal file
63
src/Html/Sanitisation/UrlSanitiser.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Erusev\Parsedown\Html\Sanitisation;
|
||||
|
||||
final class UrlSanitiser
|
||||
{
|
||||
/** @var string[] */
|
||||
private static $COMMON_SCHEMES = [
|
||||
'http://',
|
||||
'https://',
|
||||
'ftp://',
|
||||
'ftps://',
|
||||
'mailto:',
|
||||
'tel:',
|
||||
'data:image/png;base64,',
|
||||
'data:image/gif;base64,',
|
||||
'data:image/jpeg;base64,',
|
||||
'irc:',
|
||||
'ircs:',
|
||||
'git:',
|
||||
'ssh:',
|
||||
'news:',
|
||||
'steam:',
|
||||
];
|
||||
|
||||
/**
|
||||
* Disable literal intepretation of unknown scheme in $url. Returns the
|
||||
* filtered version of $url.
|
||||
* @param string $url
|
||||
* @param string[]|null $permittedSchemes
|
||||
* @return string
|
||||
*/
|
||||
public static function filter($url, $permittedSchemes = null)
|
||||
{
|
||||
if (! isset($permittedSchemes)) {
|
||||
$permittedSchemes = self::$COMMON_SCHEMES;
|
||||
}
|
||||
|
||||
foreach ($permittedSchemes as $scheme) {
|
||||
if (self::striAtStart($url, $scheme)) {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
return \str_replace(':', '%3A', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param string $needle
|
||||
* @return bool
|
||||
*/
|
||||
private static function striAtStart($string, $needle)
|
||||
{
|
||||
$len = \strlen($needle);
|
||||
|
||||
if ($len > \strlen($string)) {
|
||||
return false;
|
||||
} else {
|
||||
return \strtolower(\substr($string, 0, $len)) === \strtolower($needle);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user