downgrade to kirby v3
This commit is contained in:
@@ -16,16 +16,16 @@ use Kirby\Toolkit\Dom;
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.LongVariable)
|
||||
*/
|
||||
class DomHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* List of all MIME types that may
|
||||
* be used in data URIs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedDataUris = [
|
||||
public static $allowedDataUris = [
|
||||
'data:image/png',
|
||||
'data:image/gif',
|
||||
'data:image/jpg',
|
||||
@@ -41,59 +41,55 @@ class DomHandler extends Handler
|
||||
/**
|
||||
* Allowed hostnames for HTTP(S) URLs
|
||||
*
|
||||
* @var array|true
|
||||
* @var array
|
||||
*/
|
||||
public static array|bool $allowedDomains = true;
|
||||
|
||||
/**
|
||||
* Whether URLs that begin with `/` should be allowed even if the
|
||||
* site index URL is in a subfolder (useful when using the HTML
|
||||
* `<base>` element where the sanitized code will be rendered)
|
||||
*/
|
||||
public static bool $allowHostRelativeUrls = true;
|
||||
public static $allowedDomains = [];
|
||||
|
||||
/**
|
||||
* Names of allowed XML processing instructions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedPIs = [];
|
||||
public static $allowedPIs = [];
|
||||
|
||||
/**
|
||||
* The document type (`'HTML'` or `'XML'`)
|
||||
* (to be set in child classes)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static string $type = 'XML';
|
||||
protected static $type = 'XML';
|
||||
|
||||
/**
|
||||
* Sanitizes the given string
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @return string
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed
|
||||
*/
|
||||
public static function sanitize(string $string, bool $isExternal = false): string
|
||||
public static function sanitize(string $string): string
|
||||
{
|
||||
$dom = static::parse($string);
|
||||
$dom->sanitize(static::options($isExternal));
|
||||
$dom->sanitize(static::options());
|
||||
return $dom->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates file contents
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
*/
|
||||
public static function validate(string $string, bool $isExternal = false): void
|
||||
public static function validate(string $string): void
|
||||
{
|
||||
$dom = static::parse($string);
|
||||
$errors = $dom->sanitize(static::options($isExternal));
|
||||
|
||||
// there may be multiple errors, we can only throw one of them at a time
|
||||
$dom = static::parse($string);
|
||||
$errors = $dom->sanitize(static::options());
|
||||
if (count($errors) > 0) {
|
||||
// there may be multiple errors, we can only throw one of them at a time
|
||||
throw $errors[0];
|
||||
}
|
||||
}
|
||||
@@ -102,9 +98,10 @@ class DomHandler extends Handler
|
||||
* Custom callback for additional attribute sanitization
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMAttr $attr
|
||||
* @return array Array with exception objects for each modification
|
||||
*/
|
||||
public static function sanitizeAttr(DOMAttr $attr, array $options): array
|
||||
public static function sanitizeAttr(DOMAttr $attr): array
|
||||
{
|
||||
// to be extended in child classes
|
||||
return [];
|
||||
@@ -114,9 +111,10 @@ class DomHandler extends Handler
|
||||
* Custom callback for additional element sanitization
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMElement $element
|
||||
* @return array Array with exception objects for each modification
|
||||
*/
|
||||
public static function sanitizeElement(DOMElement $element, array $options): array
|
||||
public static function sanitizeElement(DOMElement $element): array
|
||||
{
|
||||
// to be extended in child classes
|
||||
return [];
|
||||
@@ -125,8 +123,11 @@ class DomHandler extends Handler
|
||||
/**
|
||||
* Custom callback for additional doctype validation
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMDocumentType $doctype
|
||||
* @return void
|
||||
*/
|
||||
public static function validateDoctype(DOMDocumentType $doctype, array $options): void
|
||||
public static function validateDoctype(DOMDocumentType $doctype): void
|
||||
{
|
||||
// to be extended in child classes
|
||||
}
|
||||
@@ -135,36 +136,29 @@ class DomHandler extends Handler
|
||||
* Returns the sanitization options for the handler
|
||||
* (to be extended in child classes)
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @return array
|
||||
*/
|
||||
protected static function options(bool $isExternal): array
|
||||
protected static function options(): array
|
||||
{
|
||||
$options = [
|
||||
'allowedDataUris' => static::$allowedDataUris,
|
||||
'allowedDomains' => static::$allowedDomains,
|
||||
'allowHostRelativeUrls' => static::$allowHostRelativeUrls,
|
||||
'allowedPIs' => static::$allowedPIs,
|
||||
'attrCallback' => [static::class, 'sanitizeAttr'],
|
||||
'doctypeCallback' => [static::class, 'validateDoctype'],
|
||||
'elementCallback' => [static::class, 'sanitizeElement'],
|
||||
return [
|
||||
'allowedDataUris' => static::$allowedDataUris,
|
||||
'allowedDomains' => static::$allowedDomains,
|
||||
'allowedPIs' => static::$allowedPIs,
|
||||
'attrCallback' => [static::class, 'sanitizeAttr'],
|
||||
'doctypeCallback' => [static::class, 'validateDoctype'],
|
||||
'elementCallback' => [static::class, 'sanitizeElement'],
|
||||
];
|
||||
|
||||
// never allow host-relative URLs in external files as we
|
||||
// cannot set a `<base>` element for them when accessed directly
|
||||
if ($isExternal === true) {
|
||||
$options['allowHostRelativeUrls'] = false;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given string into a `Toolkit\Dom` object
|
||||
*
|
||||
* @param string $string
|
||||
* @return \Kirby\Toolkit\Dom
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed
|
||||
*/
|
||||
protected static function parse(string $string): Dom
|
||||
protected static function parse(string $string)
|
||||
{
|
||||
return new Dom($string, static::$type);
|
||||
}
|
||||
|
||||
@@ -22,53 +22,60 @@ abstract class Handler
|
||||
/**
|
||||
* Sanitizes the given string
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
abstract public static function sanitize(string $string, bool $isExternal = false): string;
|
||||
abstract public static function sanitize(string $string): string;
|
||||
|
||||
/**
|
||||
* Sanitizes the contents of a file by overwriting
|
||||
* the file with the sanitized version
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\Exception If the file does not exist
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public static function sanitizeFile(string $file): void
|
||||
{
|
||||
$content = static::readFile($file);
|
||||
$sanitized = static::sanitize($content, isExternal: true);
|
||||
$sanitized = static::sanitize(static::readFile($file));
|
||||
F::write($file, $sanitized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates file contents
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
abstract public static function validate(string $string, bool $isExternal = false): void;
|
||||
abstract public static function validate(string $string): void;
|
||||
|
||||
/**
|
||||
* Validates the contents of a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\Exception If the file does not exist
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public static function validateFile(string $file): void
|
||||
{
|
||||
$content = static::readFile($file);
|
||||
static::validate($content, isExternal: true);
|
||||
static::validate(static::readFile($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of a file
|
||||
* for sanitization or validation
|
||||
*
|
||||
* @param string $file
|
||||
* @return string
|
||||
*
|
||||
* @throws \Kirby\Exception\Exception If the file does not exist
|
||||
*/
|
||||
protected static function readFile(string $file): string
|
||||
|
||||
@@ -17,28 +17,41 @@ class Html extends DomHandler
|
||||
{
|
||||
/**
|
||||
* Global list of allowed attribute prefixes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedAttrPrefixes = [
|
||||
public static $allowedAttrPrefixes = [
|
||||
'aria-',
|
||||
'data-',
|
||||
];
|
||||
|
||||
/**
|
||||
* Global list of allowed attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedAttrs = [
|
||||
public static $allowedAttrs = [
|
||||
'class',
|
||||
'id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Allowed hostnames for HTTP(S) URLs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $allowedDomains = true;
|
||||
|
||||
/**
|
||||
* Associative array of all allowed tag names with the value
|
||||
* of either an array with the list of all allowed attributes
|
||||
* for this tag, `true` to allow any attribute from the
|
||||
* `allowedAttrs` list or `false` to allow the tag without
|
||||
* any attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedTags = [
|
||||
public static $allowedTags = [
|
||||
'a' => ['href', 'rel', 'title', 'target'],
|
||||
'abbr' => ['title'],
|
||||
'b' => true,
|
||||
@@ -82,8 +95,10 @@ class Html extends DomHandler
|
||||
*
|
||||
* IMPORTANT: Use lower-case names here because
|
||||
* of the case-insensitive matching
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $disallowedTags = [
|
||||
public static $disallowedTags = [
|
||||
'iframe',
|
||||
'meta',
|
||||
'object',
|
||||
@@ -93,8 +108,10 @@ class Html extends DomHandler
|
||||
|
||||
/**
|
||||
* List of attributes that may contain URLs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $urlAttrs = [
|
||||
public static $urlAttrs = [
|
||||
'href',
|
||||
'src',
|
||||
'xlink:href',
|
||||
@@ -102,18 +119,19 @@ class Html extends DomHandler
|
||||
|
||||
/**
|
||||
* The document type (`'HTML'` or `'XML'`)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static string $type = 'HTML';
|
||||
protected static $type = 'HTML';
|
||||
|
||||
/**
|
||||
* Returns the sanitization options for the handler
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @return array
|
||||
*/
|
||||
protected static function options(bool $isExternal): array
|
||||
protected static function options(): array
|
||||
{
|
||||
return array_merge(parent::options($isExternal), [
|
||||
return array_merge(parent::options(), [
|
||||
'allowedAttrPrefixes' => static::$allowedAttrPrefixes,
|
||||
'allowedAttrs' => static::$allowedAttrs,
|
||||
'allowedNamespaces' => [],
|
||||
|
||||
@@ -23,8 +23,10 @@ class Sane
|
||||
{
|
||||
/**
|
||||
* Handler Type Aliases
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $aliases = [
|
||||
public static $aliases = [
|
||||
'application/xml' => 'xml',
|
||||
'image/svg' => 'svg',
|
||||
'image/svg+xml' => 'svg',
|
||||
@@ -34,34 +36,34 @@ class Sane
|
||||
|
||||
/**
|
||||
* All registered handlers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $handlers = [
|
||||
'html' => Html::class,
|
||||
'svg' => Svg::class,
|
||||
'svgz' => Svgz::class,
|
||||
'xml' => Xml::class,
|
||||
public static $handlers = [
|
||||
'html' => 'Kirby\Sane\Html',
|
||||
'svg' => 'Kirby\Sane\Svg',
|
||||
'svgz' => 'Kirby\Sane\Svgz',
|
||||
'xml' => 'Kirby\Sane\Xml',
|
||||
];
|
||||
|
||||
/**
|
||||
* Handler getter
|
||||
*
|
||||
* @param string $type
|
||||
* @param bool $lazy If set to `true`, `null` is returned for undefined handlers
|
||||
* @return \Kirby\Sane\Handler|null
|
||||
*
|
||||
* @throws \Kirby\Exception\NotFoundException If no handler was found and `$lazy` was set to `false`
|
||||
*/
|
||||
public static function handler(
|
||||
string $type,
|
||||
bool $lazy = false
|
||||
): Handler|null {
|
||||
public static function handler(string $type, bool $lazy = false)
|
||||
{
|
||||
// normalize the type
|
||||
$type = mb_strtolower($type);
|
||||
|
||||
// find a handler or alias
|
||||
$handler = static::$handlers[$type] ?? null;
|
||||
|
||||
if ($alias = static::$aliases[$type] ?? null) {
|
||||
$handler ??= static::$handlers[$alias] ?? null;
|
||||
}
|
||||
$handler = static::$handlers[$type] ??
|
||||
static::$handlers[static::$aliases[$type] ?? null] ??
|
||||
null;
|
||||
|
||||
if (empty($handler) === false && class_exists($handler) === true) {
|
||||
return new $handler();
|
||||
@@ -78,12 +80,13 @@ class Sane
|
||||
* Sanitizes the given string with the specified handler
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize(string $string, string $type, bool $isExternal = false): string
|
||||
public static function sanitize(string $string, string $type): string
|
||||
{
|
||||
return static::handler($type)->sanitize($string, $isExternal);
|
||||
return static::handler($type)->sanitize($string);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,19 +96,19 @@ class Sane
|
||||
* the extension and MIME type if not specified
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param string $file
|
||||
* @param string|bool $typeLazy Explicit handler type string,
|
||||
* `true` for lazy autodetection or
|
||||
* `false` for normal autodetection
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\LogicException If more than one handler applies
|
||||
* @throws \Kirby\Exception\NotFoundException If the handler was not found
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public static function sanitizeFile(
|
||||
string $file,
|
||||
string|bool $typeLazy = false
|
||||
): void {
|
||||
public static function sanitizeFile(string $file, $typeLazy = false): void
|
||||
{
|
||||
if (is_string($typeLazy) === true) {
|
||||
static::handler($typeLazy)->sanitizeFile($file);
|
||||
return;
|
||||
@@ -134,16 +137,17 @@ class Sane
|
||||
/**
|
||||
* Validates file contents with the specified handler
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @param string $type
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\NotFoundException If the handler was not found
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public static function validate(string $string, string $type, bool $isExternal = false): void
|
||||
public static function validate(string $string, string $type): void
|
||||
{
|
||||
static::handler($type)->validate($string, $isExternal);
|
||||
static::handler($type)->validate($string);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,26 +155,24 @@ class Sane
|
||||
* the sane handlers are automatically chosen by
|
||||
* the extension and MIME type if not specified
|
||||
*
|
||||
* @param string $file
|
||||
* @param string|bool $typeLazy Explicit handler type string,
|
||||
* `true` for lazy autodetection or
|
||||
* `false` for normal autodetection
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\NotFoundException If the handler was not found
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public static function validateFile(
|
||||
string $file,
|
||||
string|bool $typeLazy = false
|
||||
): void {
|
||||
public static function validateFile(string $file, $typeLazy = false): void
|
||||
{
|
||||
if (is_string($typeLazy) === true) {
|
||||
static::handler($typeLazy)->validateFile($file);
|
||||
return;
|
||||
}
|
||||
|
||||
$handlers = static::handlersForFile($file, $typeLazy === true);
|
||||
|
||||
foreach ($handlers as $handler) {
|
||||
foreach (static::handlersForFile($file, $typeLazy === true) as $handler) {
|
||||
$handler->validateFile($file);
|
||||
}
|
||||
}
|
||||
@@ -179,13 +181,12 @@ class Sane
|
||||
* Returns all handler objects that apply to the given file based on
|
||||
* file extension and MIME type
|
||||
*
|
||||
* @param string $file
|
||||
* @param bool $lazy If set to `true`, undefined handlers are skipped
|
||||
* @return array<\Kirby\Sane\Handler>
|
||||
*/
|
||||
protected static function handlersForFile(
|
||||
string $file,
|
||||
bool $lazy = false
|
||||
): array {
|
||||
protected static function handlersForFile(string $file, bool $lazy = false): array
|
||||
{
|
||||
$handlers = $handlerClasses = [];
|
||||
|
||||
// all values that can be used for the handler search;
|
||||
@@ -197,10 +198,7 @@ class Sane
|
||||
$handlerClass = $handler ? get_class($handler) : null;
|
||||
|
||||
// ensure that each handler class is only returned once
|
||||
if (
|
||||
$handler &&
|
||||
in_array($handlerClass, $handlerClasses) === false
|
||||
) {
|
||||
if ($handler && in_array($handlerClass, $handlerClasses) === false) {
|
||||
$handlers[] = $handler;
|
||||
$handlerClasses[] = $handlerClass;
|
||||
}
|
||||
|
||||
@@ -33,16 +33,20 @@ class Svg extends Xml
|
||||
|
||||
/**
|
||||
* Global list of allowed attribute prefixes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedAttrPrefixes = [
|
||||
public static $allowedAttrPrefixes = [
|
||||
'aria-',
|
||||
'data-',
|
||||
];
|
||||
|
||||
/**
|
||||
* Global list of allowed attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedAttrs = [
|
||||
public static $allowedAttrs = [
|
||||
// core attributes
|
||||
'id',
|
||||
'lang',
|
||||
@@ -262,17 +266,12 @@ class Svg extends Xml
|
||||
'zoomAndPan',
|
||||
];
|
||||
|
||||
/**
|
||||
* Allowed hostnames for HTTP(S) URLs
|
||||
*
|
||||
* @var array|true
|
||||
*/
|
||||
public static array|bool $allowedDomains = [];
|
||||
|
||||
/**
|
||||
* Associative array of all allowed namespace URIs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedNamespaces = [
|
||||
public static $allowedNamespaces = [
|
||||
'' => 'http://www.w3.org/2000/svg',
|
||||
'xlink' => 'http://www.w3.org/1999/xlink'
|
||||
];
|
||||
@@ -283,8 +282,10 @@ class Svg extends Xml
|
||||
* for this tag, `true` to allow any attribute from the
|
||||
* `allowedAttrs` list or `false` to allow the tag without
|
||||
* any attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $allowedTags = [
|
||||
public static $allowedTags = [
|
||||
'a' => true,
|
||||
'altGlyph' => true,
|
||||
'altGlyphDef' => true,
|
||||
@@ -359,8 +360,10 @@ class Svg extends Xml
|
||||
*
|
||||
* IMPORTANT: Use lower-case names here because
|
||||
* of the case-insensitive matching
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $disallowedTags = [
|
||||
public static $disallowedTags = [
|
||||
'animate',
|
||||
'color-profile',
|
||||
'cursor',
|
||||
@@ -390,9 +393,10 @@ class Svg extends Xml
|
||||
* Custom callback for additional attribute sanitization
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMAttr $attr
|
||||
* @return array Array with exception objects for each modification
|
||||
*/
|
||||
public static function sanitizeAttr(DOMAttr $attr, array $options): array
|
||||
public static function sanitizeAttr(DOMAttr $attr): array
|
||||
{
|
||||
$element = $attr->ownerElement;
|
||||
$name = $attr->name;
|
||||
@@ -406,13 +410,12 @@ class Svg extends Xml
|
||||
Str::startsWith($value, '#') === true
|
||||
) {
|
||||
// find the target (used element)
|
||||
$id = str_replace('"', '', mb_substr($value, 1));
|
||||
$path = new DOMXPath($attr->ownerDocument);
|
||||
$target = $path->query('//*[@id="' . $id . '"]')->item(0);
|
||||
$id = str_replace('"', '', mb_substr($value, 1));
|
||||
$target = (new DOMXPath($attr->ownerDocument))->query('//*[@id="' . $id . '"]')->item(0);
|
||||
|
||||
// the target must not contain any other <use> elements
|
||||
if (
|
||||
$target instanceof DOMElement &&
|
||||
is_a($target, 'DOMElement') === true &&
|
||||
$target->getElementsByTagName('use')->count() > 0
|
||||
) {
|
||||
$errors[] = new InvalidArgumentException(
|
||||
@@ -430,16 +433,17 @@ class Svg extends Xml
|
||||
* Custom callback for additional element sanitization
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMElement $element
|
||||
* @return array Array with exception objects for each modification
|
||||
*/
|
||||
public static function sanitizeElement(DOMElement $element, array $options): array
|
||||
public static function sanitizeElement(DOMElement $element): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
// check for URLs inside <style> elements
|
||||
if ($element->tagName === 'style') {
|
||||
foreach (Dom::extractUrls($element->textContent) as $url) {
|
||||
if (Dom::isAllowedUrl($url, $options) !== true) {
|
||||
if (Dom::isAllowedUrl($url, static::options()) !== true) {
|
||||
$errors[] = new InvalidArgumentException(
|
||||
'The URL is not allowed in the "style" element' .
|
||||
' (around line ' . $element->getLineNo() . ')'
|
||||
@@ -455,8 +459,11 @@ class Svg extends Xml
|
||||
/**
|
||||
* Custom callback for additional doctype validation
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMDocumentType $doctype
|
||||
* @return void
|
||||
*/
|
||||
public static function validateDoctype(DOMDocumentType $doctype, array $options): void
|
||||
public static function validateDoctype(DOMDocumentType $doctype): void
|
||||
{
|
||||
if (mb_strtolower($doctype->name) !== 'svg') {
|
||||
throw new InvalidArgumentException('Invalid doctype');
|
||||
@@ -466,12 +473,11 @@ class Svg extends Xml
|
||||
/**
|
||||
* Returns the sanitization options for the handler
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @return array
|
||||
*/
|
||||
protected static function options(bool $isExternal): array
|
||||
protected static function options(): array
|
||||
{
|
||||
return array_merge(parent::options($isExternal), [
|
||||
return array_merge(parent::options(), [
|
||||
'allowedAttrPrefixes' => static::$allowedAttrPrefixes,
|
||||
'allowedAttrs' => static::$allowedAttrs,
|
||||
'allowedNamespaces' => static::$allowedNamespaces,
|
||||
@@ -483,15 +489,17 @@ class Svg extends Xml
|
||||
/**
|
||||
* Parses the given string into a `Toolkit\Dom` object
|
||||
*
|
||||
* @param string $string
|
||||
* @return \Kirby\Toolkit\Dom
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed
|
||||
*/
|
||||
protected static function parse(string $string): Dom
|
||||
protected static function parse(string $string)
|
||||
{
|
||||
$svg = parent::parse($string);
|
||||
|
||||
// basic validation before we continue sanitizing/validating
|
||||
$rootName = $svg->document()->documentElement->nodeName;
|
||||
|
||||
if ($rootName !== 'svg') {
|
||||
throw new InvalidArgumentException('The file is not a SVG (got <' . $rootName . '>)');
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ class Svgz extends Svg
|
||||
/**
|
||||
* Sanitizes the given string
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @return string
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed or recompressed
|
||||
*/
|
||||
public static function sanitize(string $string, bool $isExternal = false): string
|
||||
public static function sanitize(string $string): string
|
||||
{
|
||||
$string = static::uncompress($string);
|
||||
$string = parent::sanitize($string, $isExternal);
|
||||
$string = parent::sanitize($string);
|
||||
$string = @gzencode($string);
|
||||
|
||||
if (is_string($string) !== true) {
|
||||
@@ -40,20 +40,22 @@ class Svgz extends Svg
|
||||
/**
|
||||
* Validates file contents
|
||||
*
|
||||
* @param bool $isExternal Whether the string is from an external file
|
||||
* that may be accessed directly
|
||||
* @param string $string
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
*/
|
||||
public static function validate(string $string, bool $isExternal = false): void
|
||||
public static function validate(string $string): void
|
||||
{
|
||||
$string = static::uncompress($string);
|
||||
parent::validate($string, $isExternal);
|
||||
parent::validate(static::uncompress($string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uncompresses the SVGZ data
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
protected static function uncompress(string $string): string
|
||||
{
|
||||
|
||||
@@ -24,18 +24,17 @@ class Xml extends DomHandler
|
||||
* Custom callback for additional element sanitization
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMElement $element
|
||||
* @return array Array with exception objects for each modification
|
||||
*/
|
||||
public static function sanitizeElement(DOMElement $element, array $options): array
|
||||
public static function sanitizeElement(DOMElement $element): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
// if we are validating an XML file, block all SVG and HTML namespaces
|
||||
if (static::class === self::class) {
|
||||
$xml = simplexml_import_dom($element);
|
||||
$namespaces = $xml->getDocNamespaces(false, false);
|
||||
|
||||
foreach ($namespaces as $namespace => $value) {
|
||||
$simpleXmlElement = simplexml_import_dom($element);
|
||||
foreach ($simpleXmlElement->getDocNamespaces(false, false) as $namespace => $value) {
|
||||
if (
|
||||
Str::contains($value, 'html', true) === true ||
|
||||
Str::contains($value, 'svg', true) === true
|
||||
@@ -55,8 +54,11 @@ class Xml extends DomHandler
|
||||
/**
|
||||
* Custom callback for additional doctype validation
|
||||
* @internal
|
||||
*
|
||||
* @param \DOMDocumentType $doctype
|
||||
* @return void
|
||||
*/
|
||||
public static function validateDoctype(DOMDocumentType $doctype, array $options): void
|
||||
public static function validateDoctype(DOMDocumentType $doctype): void
|
||||
{
|
||||
// if we are validating an XML file, block all SVG and HTML doctypes
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user